Java中什么是前向引用?

17
4个回答

16

这是一个特定的编译错误,它与类变量声明的顺序有关。为了说明问题,让我们使用一些代码:

public class ForwardReference {        
   public ForwardReference() {
      super();
   }

   public ForwardReference echoReference() {
      return this;
   }

   public void testLegalForwardReference() {
      // Illustration: Legal
      this.x = 5;
   }

   private int x = 0;

   // Illustration: Illegal
   private ForwardReference b = a.reference();
   private ForwardReference a = new ForwardReference();
}

正如您所看到的,Java允许您在类方法中引用一个类变量,即使变量的声明在方法之后。这是一种(合法的)前向引用示例,并且Java编译器支持该功能。

但您不能声明一个依赖于另一个未声明的类变量'b'的类变量'a'。具有依赖关系的类变量声明必须按其依赖关系的相反顺序出现。

另外,大多数(如果不是全部)集成开发环境都会警告您的代码是否包含非法引用错误。

非法前向引用的详细内容请参见JLS的第8.3.2.3节


3

基本上是编译器读取顺序的问题,如果你有

int c = 3
int a = b;
int b = 5;

编译器会按照从上到下的顺序读取代码,所以它会先看到第一行,声明了一个变量'c'并将其赋值为3,这是正确的。然后编译器会遇到第二行,声明了一个变量'a',并试图将其赋值给'b'。
但现在,编译器有一个问题:'b'是什么东西?它只知道'c'和最近才学到的'a',但它不知道任何叫做'b'的东西,因为对于编译器来说,它还没有被声明。因此,由于编译器无法处理所有的混淆,它停止工作,并让你自己去找出你到底做错了什么。
所以,前向引用部分指的是引用尚不存在的东西。也许是时间上的前向引用。

1
public class AnyCode {

    void print() {
        System.out.println("Value of j - " + j);   // legal
        System.out.println("Value of i  - " + i);  // legal
    }

    // CASE - 1 
    int k = i;         // illegal
    int i; 

    // CASE - 2 
    int l = j;         // legal
    static int m = j;  // illegal
    static int j;

    // CASE - 3 
    A aObj = bObj;     // illegal
    B bObj = new B();

    public static void main(String[] args) {

        /* 
           Note :- here anyCode act as a local variable and get space on stack 
           whereas the object it is referring to is present on heap. And you 
           cannot forward reference a local variable. 
        */

        anyCode.print();    // 'Cannot find symbol' error
        AnyCode anyCode = new AnyCode();
    }

}

class A {

}

class B {

}

*********参考案例 - 1*********

不允许引用实例变量,因为编译器无法确定我们正在引用的值的类型,甚至可能不存在这样的变量。

考虑一个例子:

int a = b;
boolean b = false;

如果允许在上述情况下进行前向引用,则可能会造成混乱。
int a = b; // What is b? is it a primitive variable or a value or a object reference

在上面的例子中,我决定不声明b,如果Java允许这样的赋值,那将是一场噩梦。
**********参考案例-2*********
静态变量在实例变量之前加载,因此引用静态变量并将其赋值给实例变量是完全可以的。

1
简单来说,这意味着引用(访问变量、调用函数)在代码文件中更深处的内容。
   static int x=getY();
   static int y=5;
   static int getY() { return y; }
  • x的值被设置为getY()的结果
  • 在y的值被设置为5之前,先调用了getY()
  • 因此x的值为0(默认整数)
  • y的值为5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接