实例变量声明和实例化
我想知道这两种实例化实例变量的方法有什么区别。 在任何一种情况下,它都会在创建PersonDirectory
实例时创建persons
的实例。
public class PersonDirectory { private ArrayList persons = new ArrayList(); } public class PersonDirectory { private ArrayList persons; public PersonDirectory(){ persons = new ArrayList(); } }
它们非常相似,对于基本编程,它们可以被认为是等效的。 您可能会注意到的最明显的事情是当您向PersonDirectory
添加另一个构造PersonDirectory
,如下所示:
public class PersonDirectory { private ArrayList persons; private DirectoryAdmin admin; public PersonDirectory() { persons = new ArrayList (); } public PersonDirectory(DirectoryAdmin initialAdmin) { admin = initialAdmin; } }
如果你使用第二个构造函数,你会发现在构造PersonDirectory之后, persons
为null。 这是因为Java不会自动为您运行其他构造函数。 您可以通过添加对this()
的显式调用来解决问题,该调用还运行与this
调用的签名匹配的构造函数。
public class PersonDirectory { private ArrayList persons; private DirectoryAdmin admin; public PersonDirectory() { persons = new ArrayList (); } public PersonDirectory(DirectoryAdmin initialAdmin) { this(); admin = initialAdmin; } }
但程序员经常忘记将调用添加到this(); 并且可能发现太晚了,因为他们的一个建造者是不小心写的,所以人们被遗弃了。
如果您改为使用声明内联编写初始化,则无论您调用哪个PersonDirectory构造函数,都会运行初始化,因此可以将其视为稍微不易出错。
public class PersonDirectory { private ArrayList persons = new ArrayList (); private DirectoryAdmin admin; public PersonDirectory() { } public PersonDirectory(DirectoryAdmin initialAdmin) { // don't have to worry about forgetting to call this(); admin = initialAdmin; } }
但是,有时候有理由更喜欢构造函数中的初始化。 例如,它可以为子类及其构造函数提供更多控制。
尽可能将成员变量声明为final
是一个好习惯。 这样编译器可以提醒您是否编写了一些未初始化的字段的构造函数。
内联初始化语句总是在类的构造函数之前运行。
两者都是平等的。 一旦开始添加更多元素,就会出现轻微边缘情况:
-
构造函数重载可以使初始化不一致(第一个使用
new X
,另一个使用new Y
,另一个不使用它) -
该字段可能需要额外的计算 – >构造函数更适合
-
不应在构造函数中分配静态字段值
类加载和初始化序列
-
执行静态语句/静态块
-
为实例变量分配默认值[v] [1]
- 实例变量已初始化
- 构造函数运行
- 实例初始化块在超级的所有调用(已)完成之后但在执行其余构造函数之前运行。
-
执行其余的构造函数。
http://www.coderanch.com/t/267125/java-programmer-SCJP/certification/Initializing-Sequence