scr*_*avy 18 java initialization
在官方Java指南"使用断言编程"中指出(页面上的最后一段)
很少有程序员意识到类的构造函数和方法可以在初始化之前运行.当发生这种情况时,很可能该类的不变量尚未建立,这可能导致严重和微妙的错误.
这是什么意思?这是什么时候发生的?我在日常使用Java时需要关心的是什么?
axt*_*avt 29
基本上,他们谈论以下情况:
public class Foo {
public static Foo INSTANCE = new Foo(); // Prints null
public static String s = "bar";
public Foo() {
System.out.println(s);
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,在这种情况下,构造函数在静态字段的初始化程序之前运行s,即在类的完全初始化之前运行.这只是一个简单的例子,但是当涉及多个类时它会变得更加复杂.
这不是你在日常工作中经常看到的东西,但你需要意识到这种可能性,并在编写代码时避免使用它.
例如,考虑构造函数中的虚方法分派.
class Foo {
Foo() {
int a = bar();
b = 7;
}
private int b;
protected int baz() { assert b == 7; return b; } ;
protected abstract int bar();
}
Run Code Online (Sandbox Code Playgroud)
如果一个子类碰巧baz在他们的实现中调用bar它们就会触及断言.该对象尚未完成构造,因此Foo基类处于某种状态.