方法局部内部类不能使用方法内声明的变量(method-local inner class canno

2019-10-17 03:42发布

为什么一个方法局部内部类不能使用除了那些标记为最终封闭的方法内声明的变量,我知道,虽然内部类实例保持有效的封闭的方法内声明的变量可能会消失,但有什么变化时,这个变量/ s的声明为final?

Answer 1:

其原因是,它是在指定的Java语言规范8.1.3#

任何局部变量,形式参数,或使用了何种异常参数,而不是在一个内部类中声明必须被声明为final。

还要注意的是Lambda项目(Java 8),其目的是在Java中引入闭包(更换匿名类),引入有效地最终的概念,这将让你为你所不懂的lambda表达式中使用非最终变量,只要吨修改它封闭之内。



Answer 2:

当变量是最后,一个副本被放置在内部类。 也就是说,它仍然无法访问的变量,但它有一个副本,它可以使用。

如果你使用反射或利用调试器,你可以看到这些副本。



Answer 3:

原因是[其实从结论存储在何处的Java最终局部变量? ]: final variables are copied by the compiler into a hidden member variable of the inner class that references it. This way, they are guaranteed to not change after the copy has been made. final variables are copied by the compiler into a hidden member variable of the inner class that references it. This way, they are guaranteed to not change after the copy has been made.

也可能是:该方法-局部内部类,这是在堆上并且其在栈上具有不同的范围可变。 但是,如果局部变量是由最终标记,它被保存在堆上。



Answer 4:

现在,起初我想点亮时

是否最终局部变量获得存储在堆而不是堆栈?

说明:现在,经过一番研究中,所以我发现,所有的局部变量( 最终与否 )存储到堆栈和走出去的范围时,该方法执行结束。

但是关于最后一个变量JVM把这些作为常数,因为他们将不会改变开始后。 当一个内部类试图访问这些编译器创建变量(不是可变它自己)到堆中的副本,并创建内部类中的合成场 ,所以即使在方法执行结束这是因为内访问类有它自己的拷贝。 合成的场均提起这实际上并不在源代码,但编译器创建存在一些内部类这些领域,使这些领域的访问。 在简单的文字隐藏字段。

所以最终变量也被存储在栈但副本可变其中内部类已经存储在堆。

所以,现在想想方法活在堆栈上的后援局部变量和只存在于方法的生命周期。 我们已经知道,一个局部变量的范围仅限于该变量在声明的方法。当方法结束时,堆栈帧吹走变量是历史。 但该方法完成后,也内它创建的内部类对象可能仍然在堆上活着如果,例如,它的一个引用被传递到一些其他的代码,然后存储在一个实例变量。 因为局部变量,但不保证活着,只要方法的局部内部类对象,内部类对象不能使用它们。 除非局部变量标记为final。 并有利于使最后的变量,因为它可以保持像合成领域。



Answer 5:

最后,确保你不会失去参考变量。 你不想让你的内部类破坏或失去你的参考,因为你可能会继续在被宣布为环境中使用它。



文章来源: method-local inner class cannot use variables declared within the method
标签: java scjp