1

请看一下这个片段:

public class A {
    void method() {
        System.out.print(B.j);//This is legal!
        class C {
            void method () {
                System.out.print(j);//This is illegal!
            }
        }
        final int j = 10;
        class D {
            void method() {
                System.out.print(j);//This is legal!
            }
        }
    }
}
class B {
    static int j = 10;
}

我们可以在定义之前在某个地方访问“Bj”,而在 C 类中访问“final int j”的情况下这是非法的。

java编译器是否将本地类视为简单的变量/对象?特别是,这种行为背后的原因是什么?我的意思是前向检查适用于 Bj,但不适用于 C 类中的“j”。

4

2 回答 2

5

我相信这是简单的范围界定。如果你用简单的 System.out.println() 调用替换你的内部类,

public class A {
  void method() {
    System.out.print(j);//This is illegal!
    final int j = 10;
    System.out.print(j);//This is legal!
  }
}

你会发现你收到了同样的信息。局部变量的范围从声明它们的地方开始,一直持续到声明它们的块的末尾。

要回答关于 B 参考的问题:考虑

public class A {
  void method() {
    System.out.print(k);//This is legal!
  }
  int k=17;
}

Java 不是单遍编译。类及其公开的字段和方法可以被前向引用。一个深思熟虑的决定是局部变量不能被前向引用。我猜这是为了让程序员在不必使用额外级别的{}块语句的情况下建立受限范围——如果我引入一个新变量,尤其是在初始化时,我不希望任何人在此之前篡改它。

这就是 Java 局部变量的工作方式。这可能不是一个令人满意的答案,但它是我们得到的最好的答案。

于 2014-03-01T06:22:32.613 回答
0

设置您的代码无法编译的可能性...

当类加载器将 A 类加载到内存中时,B 类也是如此,因为它们在同一个文件中。method因此,在运行时调用时,Bj 已经在堆上分配。

另一方面,当您在方法中声明变量时,这些变量会在调用方法时存储在堆栈中,按照您编写它们的顺序,所以这里的顺序很重要。

于 2014-03-01T06:18:34.923 回答