17

我已经通过 这个关于前向引用的合法性的问题,但不清楚forward referencesJava 语言中的含义。有人可以在一个例子的帮助下解释吗?

4

4 回答 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”。依赖类变量声明必须以它们依赖的相反顺序出现。

切线,如果您的代码包含非法引用错误,大多数(如果不是所有)IDE 都会警告您。

JLS 的第 8.3.2.3 节涵盖了非法的前向引用。

于 2013-01-24T20:25:30.203 回答
3

它基本上只是编译器读取内容的顺序,如果你有的话

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

编译器会从上到下读取它,所以它会设置第一行,它声明一个变量'c',并将它分配给3,这很好,然后它会遇到第二行,它声明一个变量' a',然后尝试将其分配给'b'。

但是现在,编译器有一个问题:这个'b'是什么东西?它才知道'c',最近才知道'a',但它不知道任何叫做'b'的东西,因为对于编译器来说,它还没有被声明。那么,由于编译器无法处理所有的混乱,它会停下来,让你弄清楚你做了什么来激怒它。

因此,前向引用部分将是对尚不存在的事物的引用。也许及时向前..

于 2013-01-24T20:33:27.097 回答
1

简单来说,它意味着引用(访问变量、调用函数)在代码文件的更下方。

   static int x=getY();
   static int y=5;
   static int getY() { return y; }
  • x 的值设置为 getY() 的结果
  • 在 y 的值设置为 5 之前调用 getY()
  • 因此 x 的值为 0(默认整数)
  • y 的值为 5
于 2013-01-24T19:53:30.350 回答
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*********

静态变量在实例变量之前加载,因此前向引用静态变量并将它们分配给实例变量非常好

于 2017-07-29T09:29:53.850 回答