请看一下这个片段:
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'。
答案 0 :(得分: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局部变量恰好起作用的方式。这可能不是一个令人满意的答案,但它是我们得到的最好的答案。
答案 1 :(得分:0)
设置代码不会编译的可能性......
当类A由类加载器加载到内存中时,类B也是如此,因为它们在同一个文件中。因此,在运行时调用method
时,已经在堆上分配了B.j.
另一方面,当您在方法中声明变量时,这些变量会在调用方法时按照您编写它们的顺序存储在堆栈中,因此这里的顺序很重要。