这两种方法都有什么优势吗?
示例1:
class A {
B b = new B();
}
示例2:
class A {
B b;
A() {
b = new B();
}
}
这两种方法都有什么优势吗?
示例1:
class A {
B b = new B();
}
示例2:
class A {
B b;
A() {
b = new B();
}
}
当前回答
使用依赖注入或延迟初始化总是更可取的,已经在其他回答中详细解释过了。
当你不想或不能使用这些模式时,对于基元数据类型,有三个令人信服的原因,我可以想到为什么最好在构造函数之外初始化类属性:
避免重复=如果你有多个构造函数,或者当你需要添加更多构造函数时,你将不必在所有构造函数体中重复初始化; 改进的可读性=你可以很容易地从类外部判断哪些变量需要初始化; 减少代码行数=在声明时每执行一次初始化,构造函数中就会减少一行。
其他回答
第二个例子是惰性初始化。第一个是更简单的初始化,它们本质上是一样的。
例2不太灵活。如果您添加了另一个构造函数,则需要记住在该构造函数中实例化字段。直接实例化字段,或者在getter中引入延迟加载。
如果实例化需要的不仅仅是一个简单的new,请使用初始化块。不管使用的构造函数是什么,这个函数都将运行。如。
public class A {
private Properties properties;
{
try {
properties = new Properties();
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("file.properties"));
} catch (IOException e) {
throw new ConfigurationException("Failed to load properties file.", e); // It's a subclass of RuntimeException.
}
}
// ...
}
我今天以一种有趣的方式被烧伤了:
class MyClass extends FooClass {
String a = null;
public MyClass() {
super(); // Superclass calls init();
}
@Override
protected void init() {
super.init();
if (something)
a = getStringYadaYada();
}
}
看到错误了吗?结果是,在父类构造函数被调用之后才调用a = null初始化式。由于超类构造函数调用init(), a的初始化之后是a = null初始化。
其实很不一样:
声明发生在构建之前。因此,如果在两个位置都初始化了变量(本例中为b),构造函数的初始化将取代在类级别所做的初始化。
所以在类级别声明变量,在构造函数中初始化它们。
我认为例2更可取。我认为最佳实践是在构造函数外部声明,并在构造函数中初始化。