要回答您的问题,您需要了解有关JVM如何工作的基础知识。当编译包含内部类的类时,生成的字节码实际上并未将内部类实现为类中的类。
错误原因:局部变量是从内部类访问的,需要将其声明为final
import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import javax.swing.JMenu;import javax.swing.JPanel;public class foo extends JPanel{ public foo() { final JMenu edit = new JMenu(); edit.getItem(0).addMouseListener(new MouseAdapter(){ @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 1) { edit.getItem(0).setEnabled(true); } } }); }}编译此程序时,将创建两个文件Foo.class和Foo $ 1.class。现在,您的问题来了,因为
Second类ie
foo$1.class不知道类ie 中
Variable
edit是否存在
First该类
foo.class。
那么如何解决这个问题呢?是什么
JVM呢,就是, 它使开发人员,使外部类的变量被声明为final的要求 。
现在完成了,现在JVM在第二个编译的类文件中安静地放置了一个名为val $ edit的隐藏变量,这是从
javap
foo.class的输出
C:MineJAVAJ2SEfolder>javap foo.classCompiled from "foo.java"public class foo extends javax.swing.JPanel { public foo();}现在,edit对于构造函数是本地的,因此输出如上。
C:MineJAVAJ2SEfolder>javap foo$1.classCompiled from "foo.java"class foo$1 extends java.awt.event.MouseAdapter { final javax.swing.JMenu val$edit; final foo this$0; foo$1(foo, javax.swing.JMenu); public void mouseClicked(java.awt.event.MouseEvent);}在
Variable因为现在编译器知道,因为它已经被声明为final的价值不能被改变,因此它的工作原理这次VAL $编辑分配已分配给编辑的值相同。
现在,如果我改变
edit
Variable的是
Local对是
Instance。现在
edit,如果更改了该变量,该类的对象就知道所有有关此变量的信息。因此,同样更改上面的程序,我们得到:
import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import javax.swing.JMenu;import javax.swing.JPanel;public class foo extends JPanel{ JMenu edit = new JMenu(); public foo() {edit.getItem(0).addMouseListener(new MouseAdapter(){ @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 1) { edit.getItem(0).setEnabled(true); } } }); }}在这种情况下,我们不假定将其声明和定义为as
final,因为在这种情况下,由于在
Variable整个类中都是Local,所以
Variable将连同
Object Referenceie
一起发送到内部类
this
C:MineJAVAJ2SEfolder>javap foo.classCompiled from "foo.java"public class foo extends javax.swing.JPanel { javax.swing.JMenu edit; public foo();}这是
Variable在这种情况下,即this $ 0发送的方式:
C:MineJAVAJ2SEfolder>javap foo$1.classCompiled from "foo.java"class foo$1 extends java.awt.event.MouseAdapter { final foo this$0; foo$1(foo); public void mouseClicked(java.awt.event.MouseEvent);}根据我的说法,这种情况似乎是一种解释。刚才我在互联网上发现了有关本地内部类无障碍获取之谜的精彩解释,也许这将有助于您更好地了解情况:-)



