请看一下这个片段:
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;
}
我们可以在定义之前的某个地方访问“B.j”,但在访问类 C 中的“final int j”的情况下这是非法的。
java编译器是否将本地类视为简单的变量/对象?特别是,这种行为背后的理由是什么?我的意思是前向检查对 B.j 有效,但对 C 类中的“j”不起作用。
我相信这是简单的范围界定。如果您用简单的 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 局部变量的工作原理。这可能不是一个令人满意的答案,但这是我们得到的最好的答案。
设置代码无法编译的可能性......
当类 A 被类加载器加载到内存中时,类 B 也被加载到内存中,因为它们位于同一个文件中。因此,当运行时调用
method
时,B.j 已经在堆上分配了。
另一方面,当您在方法中声明变量时,这些变量会在调用该方法时按照您编写它们的顺序存储在堆栈中,因此这里的顺序很重要。