来自java 语言规范8.3.2.3:
http://docs.oracle.com/javase/specs/jls/se7/html/
class Test1 {
    int i = j;  // compile-time error:
                // incorrect forward reference
    int j = 1;
}

class Z {
    static int i = j + 2; 
    static int j = 4;
}
都会报"非法向前引用",我的理解是在变量声明之前使用了它,c语言中这样做是正常的,使用方法和变量之前都要先定义或者声明,习惯了java中方法可以不按顺序随便写(当然变量最好不要乱放位置)就感觉有点奇怪.
java语言规范中有一句不太明白的解释:
The restrictions above are designed to catch, at compile time, circular or otherwise malformed initializations但是方法却不以这种形式来检查,所以以下代码不会报错,而且执行的结果为0:
class Z {
    static int peek() { return j; }
    static int i = peek();
    static int j = 1;
}
class Test {
    public static void main(String[] args) {
        System.out.println(Z.i);
    }
}
想请教一下,为什么要这样规定,是为了规避什么问题??

解决方案 »

  1.   

    int i = j;
    这时候j还没被声明,所以编译异常这个很好理解。
      

  2.   

    我印象中,只有方法和类。可以消除向前引用。为什么方法和类,可以消除向前引用。确实跟如何编译应该是有关的。但是,为什么楼主说的那种情况是不行的呢?其实你可以这么理解。
    public class Test { public static void main(String[] args) throws Exception{
    int i = j; //(1)
    int j = 10; //(2)
    }

    }程序是动态执行的。运行到(1)的时候,栈里面还没有j所以int i = j;是错误的。编译器编译的时候检查出了这种错误。所以不行。
      

  3.   

    java中变量,方法,类之间还是有很多区别的。
    方法可以,变量不一定可以
      

  4.   


    类加载分装载->链接->初始化三个阶段,在链接阶段的准备阶段中所有类变量和成员变量都已经分配了所需的空间了,最后初始化阶段引用的变量当然已经定义了,所以跟你这里举例的不一样,方法里边的变量都是存在栈上的.肯定出于某种目的才做了这种编译期间报错的防范.
      

  5.   

    事实上可以用一个未初始化的值来初始化:
    public class T{
     private static int j;
     private static int i = (j+2);
     static{
      j = 1; 
    }
    public static void main(String[] args){
     System.out.println(i);
    }
    }
    打印i的值为2而不是3
      

  6.   

    大概明白了一些,查看java解惑一书第49条,这种初始化属于一种类初始化循环,它们可能会导致在静态字段被初始化之前就调用构造器.静态字段,甚至是final类型的静态字段,可能会在它们被初始化之前,被读走其默认值.因此"非法向前引用"这种编译报错的机制在一定程度上避免了这种被读走默认值的情况发生,因为由这种类初始化循环所引发的问题是难以诊断的.结贴了
      

  7.   


    不可能。不new对象。不会分配成员变量的空间。成员变量是属于对象的。当你new对象的时候,就会发生的说的那种情况。
      

  8.   

    Quote: 引用 9 楼 dr8737010 的回复:
    类加载分装载->链接->初始化三个阶段,在链接阶段的准备阶段中所有类变量和成员变量都已经分配了所需的空间了,最后初始化阶段引用的变量当然已经定义了,所以跟你这里举例的不一样,方法里边的变量都是存在栈上的.
     
    肯定出于某种目的才做了这种编译期间报错的防范.正解!这才是问题的关键!