public class Hello {
public static final Hello h = new Hello();
static int i = 5;
int j = i;
private void print() {
System.out.println(i+" , "+j);
}
public static void main(String[] args) {
h.print();
}
}
此代码输出为5,0。 如果原因是静态加载在类中,我初始化并且j不是。但如果我从i中删除静态
public class Hello {
public static final Hello h = new Hello();
int i = 5;
int j = i;
private void print() {
System.out.println(i+" , "+j);
}
public static void main(String[] args) {
h.print();
}
}
现在为什么输出是5,5。然后当i和j初始化时。 请解释原因。
答案 0 :(得分:16)
静态块按顺序执行。
首先创建一个Hello对象,此时i = 0
尚未设置。
此后才i = 5
您必须从上到下阅读静态语句。
答案 1 :(得分:5)
在创建i
对象的那一刻,非静态变量j
和Hello
被初始化:
public static final Hello h = new Hello();
问题的第一部分Peter给了你一个答案。让我补充一下。如果您更改了静态变量的顺序:
static int i = 5;
public static final Hello h = new Hello();
int j = i;
它会打印5, 5
而不是5, 0
。
答案 2 :(得分:2)
尝试交换public static final Hello h = new Hello();
和static int i = 5;
行。
您首先初始化hello
对象(when i = 0, uninitialized)
而不是i
。首先启动i
以获得预期的行为。
答案 3 :(得分:2)
以下是您的第一个示例中发生的事情:
Hello.i
等于0. Hello.h
被实例化:
Hello.h.j
初始化为Hello.i
的当前值,即0。Hello.i
初始化为5。在你的第二个例子中,另一方面:
Hello.h
被实例化:
Hello.h.i
初始化为5。Hello.h.j
初始化为Hello.h.i
的当前值,即5。答案 4 :(得分:1)
Peter Lawrey的回答是正确的,你的困惑可能来自于一切都属于单一类的事实,名字就是这样,所以我想给你另一种方式来形象化你的行为,所以你的代码在逻辑上等同于以下代码:
public class Program {
public static Hello h = new Hello();
public static void main(String [] args) {
h.i = 5;
h.print();
}
}
class Hello {
public static int i = 0;
private int j = i;
public void print() {
System.out.println(i+", "+j);
}
}
答案 5 :(得分:0)
Java在类加载时执行静态初始化。因此
public static final Hello h = new Hello();
在加载 Hello 类时,创建一个 i = 5 且默认值为 j 的对象。
如果同时设置变量 i 和 j 非静态成员,则两者都将具有静态对象h 的默认值。
如果在main方法中创建一个新对象
Hello helloObj = new Hello();
它会给你想要的结果。
答案 6 :(得分:0)
在类初始化时执行类中声明的静态初始化程序(第12.4.2节)。与类变量的任何字段初始值设定项(第8.3.2节)一起,静态初始值设定项可用于初始化类的类变量。