我正在学习 Java,我正在学习的教程说 Java 不允许从方法 m2() 直接访问变量 k(下面示例中 m1() 的局部变量),因为它们是在相同的方法中创建的m1() 并且在编译时我会得到一个错误(除非 k 被声明为 final)。他们说的原因是局部变量(k)是在方法调用期间创建的,方法执行完成后销毁,但是对象(o)是在实例化对象时创建的,并且在方法执行后仍然不能销毁。所以教程说,如果你在方法 m2 执行后调用方法 m2() 或对象 o(我不知道这是怎么可能的),变量 k 将被破坏并且不可用。所以教程声称 Java 不允许这样的声明。 (不对的地方欢迎指正)
但是当我编译这个程序时工作正常。我错过了什么吗?我知道从我的解释角度来看这有点复杂,所以如果我的问题很清楚,请随时问我是否不清楚。
预先感谢您的帮助。
class innerclass_ex8
{
int x = 10;
static int y = 20;
public void m1()
{
int k = 30;
final int z = 50;
class inner {
public void m2()
{
System.out.println(x);
System.out.println(y);
System.out.println(k);
System.out.println(z);
}
}
inner o = new inner();
o.m2();
}
public static void main(String[] args)
{
innerclass_ex8 g = new innerclass_ex8();
g.m1();
}
}
最佳答案
首先,您的程序可以编译并正常运行,因为您使用的是 Java 8。如果使用 Java 7 或更低版本,它甚至无法编译。
原因和你说的一样。但我会尝试多解释一下。考虑以下代码:
public void m1() {
int k = 30;
class inner {
public void m2() {
System.out.println(k);
}
}
inner o = new inner();
k = 42; // <= Note the reassignment here.
o.m2();
}
方法调用 o.m2()
应该打印什么? “30”还是“42”?两种输出都可以合理地争论。在声明和定义方法时,变量 k
的值为 30。在调用方法时,变量 k
的值为 42。
为防止此类歧义,编译器不允许对此类内部类(本地和匿名)中使用的变量进行赋值。所以它必须是 final
。
在 Java 8 中,这一点放宽了一些。 Java 8 引入了effectively final 的概念。声明和初始化但未再次分配的变量被视为有效的最终变量。编译器允许该代码无需声明变量 final
。
事实上,在 Java 8 中尝试编译上述代码时也会出现编译器错误。
关于java - 从我们声明内部类的方法局部内部类访问局部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38291734/