以静态方式创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。
- 该类被加载
-
Foo被初始化为实例
2.a实例成员标志初始化为sFlag的值(默认为
false
) - sFlag被初始化为true
有关更多详细信息,请参阅JLS第12.4节 。
当加载类时, sFlag
和foo
字段被初始化,但是foo
被初始化!
字段flag
和sFlag
是布尔值,不能为空,所以默认情况下是false,当foo
初始化时sFlag
仍然是假的。 flag = sFlag
后这个flag
是flag = sFlag
是这样的
初始化操作的一般顺序是(在类加载之后,第一次使用之前):
- 静态(类)代码块为了它出现在代码中,
- 对象代码块,以便它出现在代码中(初始化块和赋值)。
- 构造函数
当然,我并没有把构造函数和函数体作为上面的代码块 。
我不知道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是错误的! 我希望能有用! 成功的