我想知道初始化像ArrayList<>这样的对象是否有区别和字段声明或构造函数中的东西。
内存使用情况,性能或类似情况是否存在差异,还是完全相同?
选项1:
class MyClass {
private List<String> strings = new ArrayList<String>();
}
选项2:
class MyClass {
private List<String> strings;
public MyClass() {
strings = new ArrayList<String>();
}
}
这可能是一个愚蠢的问题,或者是一个非常基本的问题,但我喜欢从一开始就建立,我喜欢理解我所看到的一切。
答案 0 :(得分:5)
存在差异:初始化时。首先初始化字段,然后构造函数触发。
在你琐碎的例子中,没有实际的区别,但是如果另一个字段依赖于List字段进行初始化,那么构造函数版本会随NPE爆炸。
考虑:
private List<String> strings = Arrays.asList("foo", "bar");
private String stringsDescription = strings.toString();
如果您将strings
的初始化移至构造函数,则stringsDescription
的初始化将随NPE一起爆炸。
答案 1 :(得分:3)
这基本上是一回事。在构造函数中执行它可以更好地控制它(例如,不同的构造函数可以执行不同的操作)但最终结果是相同的。
您将看到内存,CPU或其他任何方式都没有性能差异。
答案 2 :(得分:1)
看看这个Default constructor vs. inline field initialization
还有其他初始化值的方法:https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
恕我直言,在默认构造函数中初始化会有一点风险,除非你确定这是你唯一的构造函数。如果您有多个,则需要始终调用默认值(良好做法)或复制初始化代码。
答案 3 :(得分:0)
当您将 arrayList 声明为静态变量时会出现另一个区别,以便可以从其他类访问它而无需实例化持有它的类。在该设置中,您需要在声明时而不是在构造函数中进行初始化。考虑以下给出 NullPointerException 的示例:
import java.util.ArrayList;
public class Dogs {
public static ArrayList<Dog> dogList;
public Dogs(){
dogList = new ArrayList<>();
}
}
class Dog {
String breed;
public Dog(String breed){
this.breed = breed;
}
public static void main(String[] args) {
Dog dog1 = new Dog("pug");
Dogs.dogList.add(dog1);
}
}