这两种方法都有什么优势吗?
示例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();
}
}
当前回答
这两种方法都可以接受。注意,在后一种情况下,如果存在另一个构造函数,b=new b()可能无法初始化。将构造函数外部的初始化器代码看作一个公共构造函数,代码将被执行。
其他回答
我认为例2更可取。我认为最佳实践是在构造函数外部声明,并在构造函数中初始化。
这两种方法都可以接受。注意,在后一种情况下,如果存在另一个构造函数,b=new b()可能无法初始化。将构造函数外部的初始化器代码看作一个公共构造函数,代码将被执行。
我今天以一种有趣的方式被烧伤了:
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初始化。
例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.
}
}
// ...
}
我在回复中没有看到以下内容:
在声明时进行初始化的一个可能的优势可能是,在当今的IDE中,您可以非常容易地跳转到变量的声明(大多数情况下) Ctrl-<hover_over_the_variable>-<left_mouse_click>)在你的代码中的任何地方。然后立即看到该变量的值。否则,你必须“搜索”初始化完成的位置(主要是:构造函数)。
这个优势当然是次要的,所有其他逻辑推理,但对一些人来说,“特征”可能更重要。