这是一段Java代码:
static {
ture = 9;
}
static int ture;
{ // instance block
System.out.println(":"+ture+":");
}
它是如何编译的?初始化后已执行变量'ture'的声明。据我所知,静态块和字段按它们出现的顺序执行。
现在为什么实例块中的值9已被打印3次?顺便说一下,类的实例已经创建了3次。 这不是作业,我正在学习Java认证。
答案 0 :(得分:11)
关于第一个问题,静态块确实按它们出现的顺序处理,但是在静态块之前首先处理声明。声明作为类(JLS §12.3.2)的准备的一部分进行处理,该准备在初始化(JLS §12.4.2)之前发生。出于学习目的,整个JLS §12可能很有用,以及JLS §8,尤其是§8.6和JLS §8.7。 (感谢Ted Hopp和irreputable调用这些部分。)
您的引用代码中没有足够的信息来回答您的第二个问题。 (无论如何,在每个问题上最好问一下一个问题。)但是例如:
public class Foo {
static {
ture = 9;
}
static int ture;
{ // instance block
System.out.println(":"+ture+":");
}
public static final void main(String[] args) {
new Foo();
}
}
...仅输出:9:
一次,因为只创建了一个实例。如果删除new Foo();
行,它根本不会输出它。如果您看到:9:
三次,那么您可能会在未显示的代码中创建三个实例。
答案 1 :(得分:2)
静态初始化程序按它们出现的顺序执行,而声明根本不执行,这就是它们的名称。这就是为什么你的代码编译没有问题的原因:类结构在编译时从声明组装,静态块在运行时执行,很久就在处理完所有声明之后。
答案 2 :(得分:2)
正如其他人所说,声明的地方通常是无关紧要的。
但有时可能引起混淆:
class Z {
static int i = j + 2; // what should be the value of j here?
static int j = 4;
}
所以Java确实在前向引用上添加了一些限制: http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.2.3
您的示例是允许的,因为该字段的使用位于作业的左侧。显然,语言设计师并不认为这太混乱了。然而,如果可以的话,我们应该总是避免前向参考。