3

我想知道这两种实例化实例变量的方式有什么区别。在任何一种情况下,它都会在创建实例persons时创建实例PersonDirectory

public class PersonDirectory {
    private ArrayList<Person> persons = new ArrayList<>();

}


public class PersonDirectory {
    private ArrayList<Person> persons;
    public PersonDirectory(){
        persons = new ArrayList<Person>();
    }
}
4

3 回答 3

4

它们非常相似,以至于对于基本编程,它们可以被认为是等价的。您可能会注意到的最明显的事情是当您向 中添加另一个构造函数时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。这样,编译器可以提醒您是否编写了一个未初始化某些字段的构造函数。

内联初始化语句总是在类的构造函数之前运行。

于 2013-09-21T00:40:39.347 回答
0

两者是平等的。一旦开始添加更多元素,就会出现轻微的边缘情况:

  • 构造函数重载会使初始化不一致(第一个使用new X,另一个使用new Y,另一个根本不使用)

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

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

于 2013-09-21T00:22:04.197 回答
0

类加载和初始化序列

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

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

  3. 实例变量被初始化
  4. 构造函数运行
  5. 实例初始化块在对 super 的所有调用已经完成之后但在构造函数的其余部分执行之前运行。
  6. 其余的构造函数被执行。

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

于 2013-09-21T00:23:33.417 回答