实例变量声明和实例化

3

我想知道这两种实例化实例变量的方式有什么区别。无论哪种情况,当创建PersonDirectory实例时,它都会创建persons实例。

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

}


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

我喜欢第一种方法,但是我会把persons设为final。这会让我知道persons的空值是一个空的数组列表。 - Shawn
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;
    }
}

如果您使用第二个构造函数,您会发现在构造PersonDirectory之后,persons是null。这是因为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()的调用,可能会发现人员信息因为其中一个构造函数写得不仔细而被留空了。

如果你改为在声明中内联初始化,则无论你调用哪个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是一种良好的实践。这样编译器会提醒你是否编写了一些没有初始化的构造函数。

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


0

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

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

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

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


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接