这两种方法都有什么优势吗?
示例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.
}
}
// ...
}
其他回答
例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.
}
}
// ...
}
第二种选择更可取,因为它允许在ctors中使用不同的逻辑进行类实例化,并使用ctors链接。如。
class A {
int b;
// secondary ctor
A(String b) {
this(Integer.valueOf(b));
}
// primary ctor
A(int b) {
this.b = b;
}
}
所以第二种选择更加灵活。
我认为这几乎只是一个品味问题,只要初始化是简单的,不需要任何逻辑。
如果不使用初始化块,构造函数方法会更脆弱一些,因为如果稍后添加第二个构造函数而忘记在那里初始化b,则只有在使用最后一个构造函数时才会得到一个空b。
有关Java中初始化的更多细节,请参阅http://java.sun.com/docs/books/tutorial/java/javaOO/initial.html(以及关于初始化器块和其他不为人所知的初始化特性的解释)。
其实很不一样:
声明发生在构建之前。因此,如果在两个位置都初始化了变量(本例中为b),构造函数的初始化将取代在类级别所做的初始化。
所以在类级别声明变量,在构造函数中初始化它们。
第二个例子是惰性初始化。第一个是更简单的初始化,它们本质上是一样的。