这个代码生成技巧使用 Eclipse Galileo 中的新特性。但是,您也可以使用在这里介绍的、旧版本 Eclipse(如 Ganymede)中的某些技巧(如生成 getters 和 setters)。
在日常使用的 Eclipse 特性中,Source 菜单中用于代码生成的项目是用得最多的。我花了很多时间来学习如何有效使用它们,但是掌握了这些特性后,我就能够很快地构建 Java 类了。
例如,创建新类时,我不再花时间编写 setter 和 getter(访问器),也不用编写大部分的构造器。相反,我创建类并快速在类中输入私有变量,如清单 1 所示。
清单 1. 私有变量
public class Automobile {
private String make;
private String model;
private String year;
}
|
然后,单击 Source > Generate Getters and Setters,选择刚才输入的、想用公共访问器公开的私有变量。要使用构造器初始化部分变量,单击 Source > Generate Constructor using Fields 以快速创建构造器。只需点击几下鼠标,一个类就差不多创建完成了,具体情况取决于要用该类实现什么功能(见清单 2)。理想的情况是,新创建的代码应该遵守此前在 Eclipse 首选项中设置的代码格式规则。
清单 2. 自动创建构造器和访问器
public class Automobile {
private String make;
private String model;
private String year;
public String getMake() {
return make;
}
public Automobile(String make, String model, String year) {
super();
this.make = make;
this.model = model;
this.year = year;
}
public void setMake(String make) {
this.make = make;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
}
|
除了可以用 Source 菜单项生成代码外,还可以通过使用 Ctrl+Space 快捷键编写许多公共代码块来生成大量代码。要弄清生成特定的代码块需要使用的名称,查看 Preferences 窗口。例如,输入 lazy,然后按下 Ctrl+Space,这将生成用于延迟加载的 Java 代码。
新方法的代码生成设置在 Java > Code Style > Code Templates 下面的 Preferences 窗口中修改。
图 1. Java > Code Style > Code Templates 首选项
Preferences 窗口中的 Java > Editor > Code Templates 设置根据名称列示模板(见图 2)。仔细检查 Eclipse 带有的模板。您可以添加自己的模板,也可以导入模板。
图 2. Java > Editor > Code Templates 首选项
Eclipse Galileo 中的一个新特性是能够生成 toString() 方法。默认情况下,toString() 方法输出一个类的表示,这也许不能真正显示您想要查看的属性。检查清单 3 中的 main 方法。
清单 3. 使用
toString() 输出 Automobile
public class Main {
public static void main(String[] args) {
Automobile auto = new Automobile("Toyota", "Corolla", "1993");
System.out.println(auto.toString());
}
}
|
这个应用程序的输出如清单 4 所示。
清单 4.
Main 方法的输出Automobile@77df38fd |
在 Galileo 之前,我必须手工编写 toString() 方法。尽管编写这个小类并不是太费力,但如果一个类拥有许多字段,编写工作就会花费一些时间。我可能想做很多事情(比如检查一些空值),而不仅仅是串联一些值。也许我想使用一个 StringBuilder 来获得更好的性能。但是对于 Galileo,我可以使用 Source > Generate toString() 来完成上述所有任务,如图 3 所示。
图 3. 生成
toString()
单击 Finish 之后,新的 toString() 方法如清单 5 所示。
清单 5. 自动生成的
toString() 方法
...
@Override
public String toString() {
return "Automobile [" + (make != null ? "make=" + make + ", " : "")
+ (model != null ? "model=" + model + ", " : "")
+ (year != null ? "year=" + year : "") + "]";
}
...
|
现在,main 方法运行时,输出如清单 6 所示。
清单 6. 自动生成的
toString() 方法的输出Automobile [make=Toyota, model=Corolla, year=1993] |
即使清单 6 中显示的输出比清单 4 中的原始输出更具描述性,但调整一下输出格式使其更具可读性可能会更好,比如 “1993 Toyota Corolla (Automobile)”。自定义模板允许您调整 toString() 方法生成的输出。
删除 toString() 方法并再次单击 Source > Generate toString()。这次:
- 单击 String format 下拉列表旁边的 Edit。
- 单击 New。
图 4. 添加一个新格式
- 在 Pattern 中输入类似
${member.value} ${otherMembers} (${object.className})的内容,给它起个名称,然后单击 OK。
选中新模式,在 Generate toString() 上单击 OK。新代码如清单 7 所示。
清单 7. 更新后的
toString() 方法
...
@Override
public String toString() {
return (make != null ? make + " " : "")
+ (model != null ? model + " " : "")
+ (year != null ? year : "") + " (Automobile)";
}
...
|
现在,运行 main 方法,Automobile 对象的 toString() 输出如清单 8 所示。
清单 8. Automobile 对象的
toString() 方法的输出Toyota Corolla 1993 (Automobile) |
您还能使用 toString() 生成器处理数组。清单 9 展示了一个称为 options 的新的字符串数组。
清单 9. options 字符串数组
Automobile auto = new Automobile("Toyota", "Corolla", "1993");
String[] options = new String[] {
"Automatic Transmission",
"Power Brakes",
"Power Windows"
};
// new generated method after adding private String[] options;
auto.setOptions(options);
System.out.println(auto.toString());
// prints this:
// Toyota Corolla [Ljava.lang.String;@defb836 1993 (Automobile)
|
通常,原生 toString() 方法输出的数组表示就像对象的原始表示一样,并不真正显示内容。但是,选项 List contents of arrays instead of using native toString 改变了这种情况。选中该选项,重新生成 toString() 方法,新的输出如清单 10 所示。
清单 10. 重新生成的
toString() 方法的输出Toyota Corolla [Automatic Transmission, Power Brakes, Power Windows] 1993 (Automobile) |
如果某些数组非常大,可以通过选中 Limit number of items in arrays/collections/maps 并设置限制来约束输出的内容(见图 5)。这样做可以阻止 toString() 方法输出过多内容。
图 5. 输出数组内容并施加限制
清单 11 显示了将限制设置为 2 的情况。
清单 11. 将数组内容限制为 2
Toyota Corolla [Automatic Transmission, Power Brakes] 1993 (Automobile) |
有时,您需要创建一些规则,根据实际的字段值将您的对象变为相等的对象。这时,使用 Eclipse Galileo hashCode() 和 equals() 生成功能真的很方便。这不同于 equals() 的默认行为,因为即使默认拥有相同值的对象也不会是相等的。看看清单 12 中的代码。
清单 12.
equals() 方法的默认行为
public class Main {
public static void main(String[] args) {
Automobile auto = new Automobile("Toyota", "Corolla", "1993");
String[] options = new String[] {
"Automatic Transmission",
"Power Brakes",
"Power Windows"
};
auto.setOptions(options);
Automobile auto2 = new Automobile("Toyota", "Corolla", "1993");
String[] options2 = new String[] {
"Automatic Transmission",
"Power Brakes",
"Power Windows"
};
auto2.setOptions(options2);
System.out.println("Autos 1 and 2 are equal(): " + auto.equals(auto2));
}
}
|
即使所有属性值设置为相同的值,代码执行时也会输出 Auto 1 and 2 are equal(): false。
要改变这种行为,单击 Source > Generate hashCode() and equals() 以生成 equals() 方法的一个新版本,新的方法将比较所有字段,如下所示。
清单 13. 用新的
equals() 方法比较所有字段
@Override
public int hashCode() {
// snipped...
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Automobile other = (Automobile) obj;
if (make == null) {
if (other.make != null)
return false;
} else if (!make.equals(other.make))
return false;
if (model == null) {
if (other.model != null)
return false;
} else if (!model.equals(other.model))
return false;
if (!Arrays.equals(options, other.options))
return false;
if (year == null) {
if (other.year != null)
return false;
} else if (!year.equals(other.year))
return false;
return true;
}
|
现在,执行这段代码时,这两个对象使用覆盖后的 equals() 方法进行比较,所以二者是相同的。
Eclipse Galileo 中的另一个新特性是为 if 语句生成代码块的能力。如果您还没有将 Source > Clean Up 配置为将单行 if 语句转换为代码块,这个新特性很有用。避免使用单行 if 语句通常被认为是最佳实践,因此许多人愿意确保他们的代码遵守这个最佳实践。
Galileo 中生成 toString() 方法的新特性增强了 Eclipse 生成大量 Java 代码的能力。通过实践,您可以明确哪些代码必须手工输入,哪些代码可以自动生成,从而减少您的工作量。
学习
-
参阅 “Eclipse Galileo 简介”,了解关于 Galileo 特性的更多信息。
-
参阅 “推荐 Eclipse 阅读清单”。
-
浏览 developerWorks 上所有的 Eclipse 内容。
-
了解 dW China on Twitter。
-
您是 Eclipse 新用户?阅读 developerWorks 文章 “Eclipse 平台入门” 以了解它的起源和架构,以及如何用插件扩展 Eclipse。
-
通过查看 IBM developerWorks 的 Eclipse 项目资源 提高您的 Eclipse 技巧。
-
要收听面向软件开发人员的有趣访谈和讨论,请查看 developerWorks 播客。
- 随时关注 developerWorks 技术活动和网络广播。
-
查看免费的 developerWorks 演示中心,观看并了解 IBM 及开源技术和产品功能。
-
查阅最近将在全球举办的面向 IBM 开放源码开发人员的研讨会、交易展览、网络广播和其他 活动。
-
访问 developerWorks 开放源码专区,获得丰富的 how-to 信息、工具和项目更新,帮助您用开放源码技术进行开发,并与 IBM 产品结合使用。
获得产品和技术
-
检查 IBM alphaWorks 上最新的 Eclipse 技术下载。
-
从 Eclipse Foundation 下载 Eclipse Platform 和其他项目。
- 下载 IBM 产品评估试用版软件 或 IBM SOA Sandbox for Reuse,并开始使用来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。
-
使用 IBM 产品评估试用版软件 改进您的下一个开发项目,这些软件可以通过下载获得。
讨论
-
Eclipse Platform 新闻组 应当是讨论关于 Eclipse 的问题的第一站(选择此链接将启动默认的 Usenet 新闻阅读器应用程序并打开 eclipse.platform)。
-
Eclipse 新闻组 中有很多参考资料适用于对使用和扩展 Eclipse 感兴趣的人员。
-
参与 developerWorks 博客 并加入 developerWorks 社区。
