有人能解释一下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);
}
}
输出:
false
答案 0 :(得分:104)
foo
为空,sFlag
为假foo
)运行:
Foo
的新实例flag
的实例变量初始化程序执行 - 当前sFlag
为false,因此flag
的值为false sFlag
),将值设置为true main
运行,打印出foo.flag
,这是假的请注意,如果sFlag
被声明为final
,则会将其视为编译时常量,此时对它的所有引用基本上都会被内联到true
,所以foo.flag
也是如此。
答案 1 :(得分:12)
foo
在类的静态初始化期间实例化,并且在初始化sFlag之前,并且布尔值的默认值为false。
Foo初始化为实例
2.a实例成员标志初始化为sFlag的值(默认为false
)
有关详细信息,请参阅JLS §12.4。
答案 2 :(得分:5)
加载课程时,sFlag
和foo
字段已初始化,但foo
首先被初始化!
字段flag
和sFlag
是布尔值,不能为空,因此默认情况下,sFlag
在初始化时仍为false,foo
仍然为false。 flag = sFlag
之后的flag
是假的。就是这样
答案 3 :(得分:2)
初始化操作的一般顺序是(在加载类之后和首次使用之前):
当然,我不会将构造函数和函数体引用为上面的代码块。
我不知道final static
字段怎么样。看起来它们遵循static
字段的规则,并且在声明之前它们不能被引用,尽管先前的注释它们是在编译步骤初始化的。如果在编译错误之前引用它们:
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.");
}
}
上面的代码片段打印:
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 :(得分:1)
在第一个静态字段应该运行并在第一个内联!所以在第一行4然后5将运行,所以首先初始化foo,因为我们知道默认情况下布尔变量被初始化为假,所以首先,当foo初始化时,flag的字段是sflag,这是假的,然后sfalsg变为true不会改变旗帜(没有关系),然后在最后的主要运行和打印错误的falg! 我希望有用!成功