"很少有程序员意识到类的构造函数和方法可以在初始化之前运行"

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,即在类的完全初始化之前运行.这只是一个简单的例子,但是当涉及多个类时它会变得更加复杂.

这不是你在日常工作中经常看到的东西,但你需要意识到这种可能性,并在编写代码时避免使用它.


Jef*_*ter 5

例如,考虑构造函数中的虚方法分派.

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基类处于某种状态.