您选择时必须考虑一个重要方面:
Initializer blocks are members 类/对象,而 constructors are not . 在考虑 extension/subclassing 时这很重要:
Initializers are inherited 由子类 . (虽然,可以被遮蔽)
这意味着基本上保证子类按父类的预期初始化 .
但是,
Constructors are not inherited . (它们只是隐式调用 super() [即没有参数],或者您必须手动进行特定的 super(...) 调用 . )
这意味着隐式或隐式 super(...) 调用可能不会按父类的意图初始化子类 .
考虑一个初始化块的示例:
class ParentWithInitializer {
protected final String aFieldToInitialize;
{
aFieldToInitialize = "init";
System.out.println("initializing in initializer block of: "
+ this.getClass().getSimpleName());
}
}
class ChildOfParentWithInitializer extends ParentWithInitializer{
public static void main(String... args){
System.out.println(new ChildOfParentWithInitializer().aFieldToInitialize);
}
}
输出:
initializing in initializer block of: ChildOfParentWithInitializer init
无论子类实现什么构造函数,都将初始化该字段 .
现在考虑构造函数的这个例子:
class ParentWithConstructor {
protected final String aFieldToInitialize;
// different constructors initialize the value differently:
ParentWithConstructor(){
//init a null object
aFieldToInitialize = null;
System.out.println("Constructor of "
+ this.getClass().getSimpleName() + " inits to null");
}
ParentWithConstructor(String... params) {
//init all fields to intended values
aFieldToInitialize = "intended init Value";
System.out.println("initializing in parameterized constructor of:"
+ this.getClass().getSimpleName());
}
}
class ChildOfParentWithConstructor extends ParentWithConstructor{
public static void main (String... args){
System.out.println(new ChildOfParentWithConstructor().aFieldToInitialize);
}
}
输出:
Constructor of ChildOfParentWithConstructor inits to null null
默认情况下,这会将字段初始化为 null ,即使它可能不是您想要的结果 .