它们非常相似,以至于对于基本编程,它们可以被认为是等价的。您可能会注意到的最明显的事情是当您向 中添加另一个构造函数时PersonDirectory
,如下所示:
public class PersonDirectory {
private ArrayList<Person> persons;
private DirectoryAdmin admin;
public PersonDirectory() {
persons = new ArrayList<Person>();
}
public PersonDirectory(DirectoryAdmin initialAdmin) {
admin = initialAdmin;
}
}
如果你使用第二个构造函数,你会发现persons
在构造 PersonDirectory 之后它是空的。这是因为 Java 不会自动为您运行其他构造函数。您可以通过添加对 的显式调用来解决此问题,该调用this()
还运行与调用签名匹配的构造函数this
。
public class PersonDirectory {
private ArrayList<Person> persons;
private DirectoryAdmin admin;
public PersonDirectory() {
persons = new ArrayList<Person>();
}
public PersonDirectory(DirectoryAdmin initialAdmin) {
this();
admin = initialAdmin;
}
}
但很多时候程序员会忘记将调用添加到 this(); 并且可能会发现 people 被留空为时已晚,因为他们的构造函数之一是不小心编写的。
如果您改为在声明中写入初始化,则无论您调用哪个 PersonDirectory 构造函数,都会运行初始化,因此可以认为不太容易出错。
public class PersonDirectory {
private ArrayList<Person> persons = new ArrayList<Person>();
private DirectoryAdmin admin;
public PersonDirectory() {
}
public PersonDirectory(DirectoryAdmin initialAdmin) {
// don't have to worry about forgetting to call this();
admin = initialAdmin;
}
}
然而,有时更喜欢在构造函数中进行初始化是有原因的。例如,它可以赋予子类及其构造函数更多的控制权。
尽可能声明成员变量是一个好习惯final
。这样,编译器可以提醒您是否编写了一个未初始化某些字段的构造函数。
内联初始化语句总是在类的构造函数之前运行。