有人能解释这段代码有什么问题:
public class Base {
static {
i = 1;
System.out.println("[Base]after static init block i=" + i);// LINE 1
System.out.println("*************************************");
System.out.println();
}
static int i;
public static void main(String[] args) {
System.out.println(Base.i);
}
}
如果我评论第1行 - 一切正常,Base.main方法打印“1”。 如果没有注释LINE 1 - ,则得到编译时错误:“非法前向引用”。 所以,正如我在静态初始化块中所理解的,我可以为i设置值,但不能读取。谁能解释为什么?
答案 0 :(得分:18)
这是因为restrictions on the use of Fields during Initialization。特别是,静态初始化块在声明它们的行之前的静态字段的使用只能在表达式的左侧(即赋值),除非它们是完全限定的(在您的情况下{{1 }})。
例如:如果您在Base.i
之后插入int j = i;
,则会出现同样的错误。
解决问题的显而易见的方法是在静态初始化块之前声明i = 1;
。
答案 1 :(得分:7)
“非法转发引用”表示您在定义变量之前尝试使用该变量。
您观察到的行为是javac错误的症状(请参阅此错误报告)。问题似乎在较新版本的编译器中得到修复,例如OpenJDK 7.
看看
答案 2 :(得分:3)
您可以在静态块中将Base添加到i变量,或者必须在块之前声明static int i。其他解决方案是创建静态方法而不是静态块。
static {
Base.i = 1;
System.out.println("[Base]after static init block i=" + Base.i);// LINE 1
System.out.println("*************************************");
System.out.println();
}
答案 3 :(得分:2)
将您的代码更改为:
int i;
static {
i = 1;
System.out.println("[Base]after static init block i=" + i);// LINE 1
System.out.println("*************************************");
System.out.println();
}
答案 4 :(得分:0)
A variable should always be textually declared before used else Illegal forward Reference comes into picture. Only Exception to this Statement is : If prior to declaration it is used on LHS of expression. Ex :
Snippet 1:
static{
x = 10;
}
static int x;
Above snippet will work.
Snippet 2:
static{
System.out.println("Value of x: " + x)
}
static int x;
This will give CTE, because x isnt LHS of expression.
Keeping those conditions in mind we can avoid Illegal Forward ref issue in our code.
Thanks