为什么 Java 内部类需要“最终”外部实例变量?

2022-08-31 15:50:57
final JTextField jtfContent = new JTextField();
btnOK.addActionListener(new java.awt.event.ActionListener(){
    public void actionPerformed(java.awt.event.ActionEvent event){
        jtfContent.setText("I am OK");
    }
} );

如果我省略,我会看到错误“不能引用在不同方法中定义的内部类中的非最终变量jtfContent”。final

为什么匿名内部类必须要求外部类实例变量是最终的才能访问它?


答案 1

好吧,首先,让我们都放松一下,请把枪放下。

还行。现在,该语言坚持这样做的原因是,它作弊是为了让你的内部类函数访问它们渴望的局部变量。运行时会复制本地执行上下文(并根据需要等),因此它坚持要求你制作所有内容,以便它可以保持诚实。final

如果它没有这样做,那么在构造对象之后但在内部类函数运行之前更改局部变量值的代码可能会令人困惑和奇怪。

这是围绕Java和“闭包”的许多brouhaha的本质。


注意:开头一段是一个笑话,指的是OP原始构图中的一些全大写文本。


答案 2

匿名类中的方法实际上不能访问局部变量和方法参数。相反,当实例化匿名类的对象时,对象的方法引用的最终局部变量和方法参数的副本将作为实例变量存储在对象中。匿名类对象中的方法确实访问这些隐藏的实例变量。[1]

因此,必须将局部类的方法访问的局部变量和方法参数声明为 final,以防止它们在实例化对象后更改其值。

[1] http://www.developer.com/java/other/article.php/3300881/The-Essence-of-OOP-using-Java-Anonymous-Classes.htm


推荐