Java中的内部块如何访问应该超出范围的局部变量? (JVM如何处理J
在以下代码中:
public class Main { Emp globalEmp; public void aMethod() { final int stackVar = 10; globalEmp = new Emp() { public void doSomeThing() { System.out.println("stackVar :" + stackVar); } }; } public static void main(String[] args) { Main m = new Main(); m.aMethod(); m.globalEmp.doSomeThing(); } } interface Emp{ public void doSomeThing(); } 据我所知,将执行以下操作: > Main m = new Main(); :将创建一个新的Main类实例,并将globalEmp设置为null. 那么,Java运行时如何真正起作用呢? 编辑: >由于运行时将创建最终局部变量的浅表副本(下面的每个答案),为什么它也不允许访问非最终变量? 解决方法
通常,匿名内部类将为其生成一个构造函数,以获取在匿名内部类的类中引用的局部变量的值.生成的代码转为:
globalEmp = new Emp() { ... }; 成: globalEmp = new Main$1(stackVar); 然后,该构造函数将值复制到生成的匿名类中的隐藏字段中. 换句话说,它会创建值的副本.之后,原始值来自的变量无关紧要. 在您实际显示的情况下,它不需要因为10是常量 – 但这是捕获变量的一般方式. 编辑:回应你的编辑… 变量必须是最终的,这样就不会出现混淆 – 如果你可以改变它们,一些开发人员可能希望在匿名类中可以看到任何变化,就像在其他闭包实现中一样. 至于围绕这个的官方文档,我在Java语言规范中看到的最接近的是section 8.1.3,尽管它没有讨论各种决策背后的动机. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |