2

可能重复:
无法引用在不同方法中定义的内部类中的非最终变量
为什么在匿名类中只能访问最终变量?

在 SO 和谷歌中寻找这个问题的答案,但找不到任何答案。

我有以下代码:

MyClass variable = new MyClass();
Button b = new Button();
b.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e){
         System.out.println("You clicked the button");
         variable.doSomething();
   }
});

编译器返回这个:

从内部类中访问局部变量变量;需要声明为final

为什么variable必须是最终的技术原因是什么?

4

2 回答 2

6

这是因为您使用的是匿名内部类。发生的是编译器为您创建类。它将它称为您的外部类并添加$和编号,例如$$2等等。

该类具有自动初始化的外部类的引用,因此其实例可以使用外部类的方法和字段。

但是你的班级是匿名的。它是在方法内部定义的,可以使用在这个匿名类之前定义内部变量。问题是“它怎么能做到?” 确实,您不能参考“运行方法的实例”来访问其变量。答案是匿名内部类引用的所有方法变量都复制到匿名内部类。因此变量必须是最终的:否则有人可以从外部类更改它们的值,并且这些更改对内部类是不可见的。

于 2012-06-10T15:15:45.883 回答
0

这是因为内部类仅在触发事件时才执行代码。如果变量没有声明为final,那么MyClass引用的对象variable可能会改变,如果内部类需要该对象,它将不知道它应该引用哪个MyClass对象。

因此,它应该被声明为最终的,所以这个引用永远不会改变。

想象一下没有 final 关键字的情况:

variable正在 创建内部类引用对象,并且MyClass在内部类中引用对象hashCode(): 12345variableMyClasshashCode(): 12345

variable更改为现在在内部类中引用 Object MyClasswithhashCode(): abcde variable仍在引用MyClassObject withhashCode(): 12345

触发事件时,Java 如何从这里运行代码?使用哪个MyClass对象?

现在使用 final 关键字:

variable正在 创建内部类引用对象,并且MyClass在内部类中引用对象hashCode(): 12345variableMyClasshashCode(): 12345

由于 final 关键字,无法更改引用。

当事件被触发时,Java 总是知道MyClass要调用哪个对象。没问题。

于 2012-06-10T15:11:06.793 回答