以静态方式创build一个对象

任何人都可以解释Java如何执行这个代码? 我的意思是执行每个语句的顺序。

public class Foo { boolean flag = sFlag; static Foo foo = new Foo(); static boolean sFlag = true; public static void main(String[] args) { System.out.println(foo.flag); } } 

OUTPUT:

 false 
  • 类初始化开始。 最初, foo为空, sFlag为false
  • 第一个静态variables初始值设定项( foo )运行:
    • Foo的新实例被创build
    • flag的实例variables初始化器执行 – 当前sFlag是假的,所以flag的值是false
  • 第二个静态variables初始值设定项( sFlag )执行,将该值设置为true
  • 类初始化完成
  • main运行,打印出foo.flag ,这是错误的

请注意,如果sFlag被声明为final那么它将被视为编译时常量 ,在这一点上,所有对它的引用将基本上被内联到true ,所以foo.flag也是如此。

foo在类的静态初始化过程中初始化,在sFlag初始化之前,布尔值的默认值为false。

  1. 该类被加载
  2. Foo被初始化为实例

    2.a实例成员标志初始化为sFlag的值(默认为false

  3. sFlag被初始化为true

有关更多详细信息,请参阅JLS第12.4节 。

当加载类时, sFlagfoo字段被初始化,但是foo被初始化!
字段flagsFlag是布尔值,不能为空,所以默认情况下是false,当foo初始化时sFlag仍然是假的。 flag = sFlag后这个flagflag = sFlag是这样的

初始化操作的一般顺序是(在类加载之后,第一次使用之前):

  1. 静态(类)代码块为了它出现在代码中,
  2. 对象代码块,以便它出现在代码中(初始化块和赋值)。
  3. 构造函数

当然,我并没有把构造函数和函数体作为上面的代码块

我不知道final static字段怎么样。 看起来他们遵循static字段的规则,并且在声明之前不能被引用,尽pipe之前的注释是在编译步骤初始化的。 如果它们在编译错误之前被引用:

 Example.java:8: illegal forward reference System.err.println("1st static block j=" + j); 

也许final static字段可以初始化并编译到类文件中,但这不是一般规则,在声明之前它们仍然不能被引用。

检查初始化顺序的示例代码:

 class Example { final static int j = 5; { System.err.println("1st initializer j=" + j); } static { System.err.println("1st static block j=" + j); } static { System.err.println("2nd static block j=" + j); } final static java.math.BigInteger i = new java.math.BigInteger("1") { { System.err.println("final static anonymous class initializer"); } }; Example() { System.err.println("Constructor"); } static { System.err.println("3nd static block j=" + j); } { System.err.println("2nd initializer"); } public static void main(String[] args) { System.err.println("The main beginning."); Example ex = new Example(); System.err.println("The main end."); } } 

上面的代码snipset打印:

 1st static block j=5 2nd static block j=5 final static anonymous class initializer 3nd static block j=5 The main beginning. 1st initializer j=5 2nd initializer Constructor The main end. 

首先静态字段应该运行,并在第一个内联! 所以在第一行4和5将运行,所以foo首先被初始化,因为我们知道布尔variables默认初始化为false,所以在foo被初始化的时候,flag的字段是sflag,这是false,然后sfalsg变成true,将不会改变标志(没有关系),然后在最后的主要运行和打印falg是错误的! 我希望能有用! 成功的