【发布时间】:2013-03-28 12:58:35
【问题描述】:
在Java中,有没有办法在超级构造函数运行之前初始化一个字段?
即使是我能想到的最丑陋的 hack 也会被编译器拒绝:
class Base
{
Base(String someParameter)
{
System.out.println(this);
}
}
class Derived extends Base
{
private final int a;
Derived(String someParameter)
{
super(hack(someParameter, a = getValueFromDataBase()));
}
private static String hack(String returnValue, int ignored)
{
return returnValue;
}
public String toString()
{
return "a has value " + a;
}
}
注意:当我从继承切换到委托时,问题就消失了,但我仍然想知道。
【问题讨论】:
-
您是否要预初始化字段
a? -
我认为你做不到。在
super调用之后,您在类中执行的任何初始化(即使它在构造函数之外)都会移动到每个构造函数。因此,超级构造函数总是在字段初始化之前运行。 -
@FredOverflow 因为
a只能在Derived中访问,为什么它被初始化之前super()被调用?之后立即初始化它不会对您提供的示例产生影响(除非您从 Base 构造函数调用覆盖的方法,这开始闻起来很腥)。 -
Effective Java Item 17: "构造函数不能直接或间接调用可重写的方法(...)如果重写方法依赖于子类构造函数执行的任何初始化,则该方法不会表现如预期。"
-
Ugly Hack:直接在 java 字节码中创建派生类,如以下答案:stackoverflow.com/questions/3278865/…
标签: java inheritance constructor initialization constructor-chaining