【问题标题】:Illegal forward Reference java issue非法转发参考java问题
【发布时间】:2013-01-31 11:42:50
【问题描述】:

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

    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 设置值,但不能读取。谁能解释一下原因?

【问题讨论】:

    标签: java


    【解决方案1】:

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

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

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

    【讨论】:

    • 我尝试了同样的例子,但没有使用 static 关键字,它的行为与这段代码相同。那么它是否也遵循相同的规则?只在 LHS 上允许有什么用,而不是我们可以抛出编译时错误。
    • 是的,静态变量和实例变量的规则是一样的。按照我的答案中的链接。
    • 旁注:模拟具有完全相同的限制。
    【解决方案2】:

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

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

    看看

    Illegal forward reference error for static final fields

    【讨论】:

    • 我认为问题中描述的行为不是错误。
    【解决方案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();
    }
    

    【讨论】:

    • 只在 System.out 语句中添加 Base 就足够了,谢谢。
    【解决方案4】:

    将您的代码更改为:

    int i;
    static {
        i = 1;
        System.out.println("[Base]after static init block i=" + i);// LINE 1
        System.out.println("*************************************");
        System.out.println();
    }
    

    【讨论】:

      【解决方案5】:
      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
      

      【讨论】:

        猜你喜欢
        • 2016-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-03
        • 2011-01-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多