这两种方法都有什么优势吗?
示例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()可能无法初始化。将构造函数外部的初始化器代码看作一个公共构造函数,代码将被执行。
其他回答
这两种方法都可以接受。注意,在后一种情况下,如果存在另一个构造函数,b=new b()可能无法初始化。将构造函数外部的初始化器代码看作一个公共构造函数,代码将被执行。
我认为这几乎只是一个品味问题,只要初始化是简单的,不需要任何逻辑。
如果不使用初始化块,构造函数方法会更脆弱一些,因为如果稍后添加第二个构造函数而忘记在那里初始化b,则只有在使用最后一个构造函数时才会得到一个空b。
有关Java中初始化的更多细节,请参阅http://java.sun.com/docs/books/tutorial/java/javaOO/initial.html(以及关于初始化器块和其他不为人所知的初始化特性的解释)。
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.
我今天以一种有趣的方式被烧伤了:
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初始化。
class MyClass extends FooClass {
String a = null;
public MyClass() {
super(); // Superclass calls init();
}
@Override
protected void init() {
super.init();
if (something)
a = getStringYadaYada();
}
}
关于以上,
String a = null;
Null init可以避免,因为它是默认值。 然而,如果您需要另一个默认值, 然后,由于初始化顺序不受控制, 我将修改如下:
class MyClass extends FooClass
{
String a;
{
if( a==null ) a="my custom default value";
}
...