“很少有程序员知道一个事实,即类的构造函数和方法可以在初始化之前运行”
2022-09-02 20:31:19
在官方Java指南“使用断言编程”中指出(页面上的最后一段)
很少有程序员知道类的构造函数和方法可以在其初始化之前运行。当这种情况发生时,很可能类的不变量尚未建立,这可能会导致严重而微妙的错误。
这是什么意思?这种情况何时发生?这是我在日常使用Java时必须关心的事情吗?
在官方Java指南“使用断言编程”中指出(页面上的最后一段)
很少有程序员知道类的构造函数和方法可以在其初始化之前运行。当这种情况发生时,很可能类的不变量尚未建立,这可能会导致严重而微妙的错误。
这是什么意思?这种情况何时发生?这是我在日常使用Java时必须关心的事情吗?
基本上,他们谈论以下情况:
public class Foo {
public static Foo INSTANCE = new Foo(); // Prints null
public static String s = "bar";
public Foo() {
System.out.println(s);
}
}
如您所见,在这种情况下,构造函数在静态字段的初始值设定项之前运行,即在类的完全初始化之前。这只是一个简单的示例,但是当涉及多个类时,它可能会变得更加复杂。s
这不是你在日常工作中经常能看到的东西,但你需要意识到这种可能性,并在编写代码时避免它。
例如,考虑构造函数中的虚拟方法调度。
class Foo {
Foo() {
int a = bar();
b = 7;
}
private int b;
protected int baz() { assert b == 7; return b; } ;
protected abstract int bar();
}
如果一个子类碰巧从他们的实现内部调用,他们就会命中断言。对象尚未完成构造,因此基类处于某种状态。baz
bar
Foo