这两种方法都有什么优势吗?
示例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();
}
}
当前回答
There is one more subtle reason to initialize outside the constructor that no one has mentioned before (very specific I must say). If you are using UML tools to generate class diagrams from the code (reverse engineering), most of the tools I believe will note the initialization of Example 1 and will transfer it to a diagram (if you prefer it to show the initial values, like I do). They will not take these initial values from Example 2. Again, this is a very specific reason - if you are working with UML tools, but once I learned that, I am trying to take all my default values outside of constructor unless, as was mentioned before, there is an issue of possible exception throwing or complicated logic.
其他回答
这两种方法都可以接受。注意,在后一种情况下,如果存在另一个构造函数,b=new b()可能无法初始化。将构造函数外部的初始化器代码看作一个公共构造函数,代码将被执行。
使用依赖注入或延迟初始化总是更可取的,已经在其他回答中详细解释过了。
当你不想或不能使用这些模式时,对于基元数据类型,有三个令人信服的原因,我可以想到为什么最好在构造函数之外初始化类属性:
避免重复=如果你有多个构造函数,或者当你需要添加更多构造函数时,你将不必在所有构造函数体中重复初始化; 改进的可读性=你可以很容易地从类外部判断哪些变量需要初始化; 减少代码行数=在声明时每执行一次初始化,构造函数中就会减少一行。
第二种选择更可取,因为它允许在ctors中使用不同的逻辑进行类实例化,并使用ctors链接。如。
class A {
int b;
// secondary ctor
A(String b) {
this(Integer.valueOf(b));
}
// primary ctor
A(int b) {
this.b = 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.
}
}
// ...
}
我认为例2更可取。我认为最佳实践是在构造函数外部声明,并在构造函数中初始化。