引用Java中匿名类的变量

时间:2010-06-26 14:43:40

标签: java anonymous-class

我正在编写一个setonclick listner,我希望能够引用该按钮,以便我可以更改其属性。即让它禁用?

我得到了这个消息:

不能在不同方法

中定义的内部类中引用非最终变量confirmButton
        confirmButton.setOnClickListener(new View.OnClickListener() {

        public void onClick(View view) {
            confirmButton.setEnabled(false);    
        }



    }); 

4 个答案:

答案 0 :(得分:3)

这是因为您可能正试图从以这种方式使用的匿名类访问该按钮:

button.addActionListener(
  new MyListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
      //do your things on button }
    }
  }
);

这不起作用,因为在Java中,匿名类无法查看在声明它们的方法中声明的变量,因为它们的作用域是分开的。让你的类看到它的唯一方法是强制final约束,它确保编译器在初始化后变量不会改变,允许它将其范围扩展到匿名类。

要快速解决此问题,您可以访问ActionEvent内的actionPerformed按钮:

((JButton)e.getSource()).setEnabled(false)

否则,您必须在某处具体声明您的ActionListener或使用staticfinal属性声明方法外的按钮..特别是如果您计划通过某个操作修改某些元素被另一个元素解雇了。

答案 1 :(得分:1)

我建议反对getSource;文档不保证它将是您的按钮。您可以在范围内创建按钮final,也可以使用更复杂的类

public class ComponentRelevantOnClickListener implements View.OnClickListener {

  private JComponent component;

  public ComponentRelevantOnClickListener(JComponent component) {
    this.component = component;
  }
}

// then, in your code...

confirmButton.setOnClickListener(new ComponentRelevantOnClickListener(confirmButton) {

    public void onClick(View view) {
        component.setEnabled(false);    
    }
});

如果你转向动作和监听器类而不是匿名子类的设计,你将有更多的机会重新使用(你已经可以看到ComponentRelevantOnClickListener可以替换为你可以使用的“DisableOnClickListneer”在任何地方为此目的),你的代码将整体设计得更好。

答案 2 :(得分:0)

匿名类中引用的变量需要在Java中定义为final。 Jon Skeet在this article内有一个很好的例子。

答案 3 :(得分:0)

匿名内部类只能访问外部作用域中的变量final。假设您只分配给confirmButton一次,我建议您将其标记为final

final JButton confirmButton = new JButton();