变量应该是最终的内部监听器

时间:2012-06-10 15:08:29

标签: java

  

可能重复:
  Cannot refer to a non-final variable inside an inner class defined in a different method
  Why are only final variables accessible in anonymous class?

在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();
   }
});

编译器返回:

  

从内部类中访问局部变量变量;需要   被宣布为最终

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

2 个答案:

答案 0 :(得分:6)

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

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

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

答案 1 :(得分:0)

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

因此,它应该被声明为final,因此这个引用永远不会改变。

想象一下没有最终关键字:

variable引用MyClass对象hashCode(): 12345 内部类已创建,内部类中的variable引用MyClass对象hashCode(): 12345

variable已更改为现在使用MyClass引用hashCode(): abcde对象 内部类中的variable仍在使用MyClass

引用hashCode(): 12345对象

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

现在使用final关键字:

variable引用MyClass对象hashCode(): 12345 内部类已创建,内部类中的variable引用MyClass对象hashCode(): 12345

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

Java始终知道触发事件时要调用的MyClass对象。没问题。