Joh*_*n N 1 java static initialization
为什么java中静态成员的顺序很重要?
例如
public class A {
static int i= 1;
static int c = i;
int a = c; <<------ ok
}
Run Code Online (Sandbox Code Playgroud)
与
public class B {
int a = c; <<--- compile error
static int c = 1;
static int i = c;
}
Run Code Online (Sandbox Code Playgroud)
为什么Java的设计使得这种排序有所不同?(我根据ykaganovich的回答编辑了我的问题)
编辑:谢谢大家的帮助!我用非静态变量测试了我的例子.它具有完全相同的行为,因此静态不起任何作用.这个问题具有误导性(至少对我而言).我会尝试总结你的答案.
编辑2:
我会尝试总结答案.欲了解更多信息,请阅读下面的答案:)
a)Java中的直接前向引用:
static int i = c;
static int c = 1;
Run Code Online (Sandbox Code Playgroud)
很混乱.所以在Java中不允许这样做.主要原因是初始化顺序.
b)Java中允许间接前向引用
public class Test {
int i = c();
int c() { return c; }
int c = 1;
}
Run Code Online (Sandbox Code Playgroud)
c)您必须准确定义变量声明(或初始化)的执行顺序,它的唯一定义是如何在java中完成此操作.在java中,这种排序是从上到下的.
d)明确定义的顺序提供了一种可预测结果的方法.
e)如果你很好地设计你的程序,你将不会遇到这个问题.
如果您实际为变量赋值,这很重要.
public class A {
static int i = 0;
static int c = i; //fine
}
Run Code Online (Sandbox Code Playgroud)
VS
public class B {
static int c = i; // compilation error
static int i = 0;
}
Run Code Online (Sandbox Code Playgroud)
**更新问题**
啊,我看到你明白这是不允许的,但你想知道原因.
让我们更有趣一点:
public class A {
static int c = boom();
static int i = bam();
private static int bam() {
return c + 2;
}
private static int boom() {
return i + 1;
}
public static void main(String[] args) throws Exception {
System.out.println("i: " + i);
System.out.println("c: " + c);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
i: 3
c: 1
Run Code Online (Sandbox Code Playgroud)
如果你移动i和c:
static int i = bam();
static int c = boom();
Run Code Online (Sandbox Code Playgroud)
你得到:
i: 2
c: 3
Run Code Online (Sandbox Code Playgroud)
这只是为了说明秩序很重要.
至于为什么不允许在变量赋值中使用前向引用,您希望此代码能做什么?
static i = c;
static c = i++;
Run Code Online (Sandbox Code Playgroud)
答案实际上是明确的,因为Java必须按照定义的特定顺序处理它.所以,这应该相当于:
static i = 0;
static c = 0;
static {
i = c;
c = i++;
}
Run Code Online (Sandbox Code Playgroud)
但第一种形式非常混乱,因此容易出错.我的猜测就是它被禁止的原因.