13

谁能解释这段代码有什么问题:

    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);
    }
}

如果我评论 LINE 1 - 一切正常并且 Base.main 方法打印“1”。如果第 1 行 - 未注释,则会出现编译时错误:“非法前向引用”。所以,正如我在静态初始化块中理解的那样,我可以为 i 设置值,但不能读取。谁能解释为什么?

4

5 回答 5

27

这是因为Initialization 期间对 Fields 使用的限制。特别是,在声明它们的行之前的静态初始化块内使用静态字段只能在表达式的左侧(即赋值),除非它们是完全限定的(在您的情况下Base.i)。

例如:如果你在你int j = i;之后插入,i = 1;你会得到同样的错误。

解决这个问题的明显方法是在静态初始化块static int i; 之前声明。

于 2013-01-31T11:46:35.263 回答
9

“非法前向引用”意味着您试图在定义变量之前使用它。

您观察到的行为是 javac 错误的症状(请参阅此错误报告)。该问题似乎在较新版本的编译器中得到修复,例如 OpenJDK 7。

看一下

静态最终字段的非法前向引用错误

于 2013-01-31T11:46:17.943 回答
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();
}
于 2013-01-31T11:52:25.750 回答
2

将您的代码更改为:

int i;
static {
    i = 1;
    System.out.println("[Base]after static init block i=" + i);// LINE 1
    System.out.println("*************************************");
    System.out.println();
}
于 2013-01-31T11:47:26.013 回答
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
于 2019-12-05T03:46:53.000 回答