实例变量声明和实例化

我想知道这两种实例化实例变量的方法有什么区别。 在任何一种情况下,它都会在创建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 ,另一个不使用它)

  • 该字段可能需要额外的计算 – >构造函数更适合

  • 不应在构造函数中分配静态字段值

类加载和初始化序列

  1. 执行静态语句/静态块

  2. 为实例变量分配默认值[v] [1]

  3. 实例变量已初始化
  4. 构造函数运行
  5. 实例初始化块在超级的所有调用(已)完成之后但在执行其余构造函数之前运行。
  6. 执行其余的构造函数。

    http://www.coderanch.com/t/267125/java-programmer-SCJP/certification/Initializing-Sequence