Java内部类中的非final变量

8

我需要在内部类中更改变量,但是我遇到了臭名昭著的“无法引用在不同方法中定义的非最终变量”的错误。

void onStart(){
  bt.setOnClickListener(new View.OnClickListener() {
     public void onClick(View v) {
       int q = i;
     }
  });
}

我很快创建了一个类,其中包含了我想要更改的所有内容,并在内部类之外制作了该类的最终版本。

class temp{
  int q;
}

void onStart(){
  final temp x = new temp();
  bt.setOnClickListener(new View.OnClickListener() {
     public void onClick(View v) {
       x.q = i;
     }
  });
}

这似乎是我需要的并且它能够工作,但我想知道这是否是正确解决问题的方法。此外,我真的不喜欢使用单词temp来命名我的类。是否有一个实际的编程术语来描述我所做的事情,以便我可以为我的类起更加描述性的名称?

4个回答

9
您可以简单地创建一个内部类来替代您当前正在使用的匿名类。这样,您就有了构造函数和任何其他设置成员变量所需的方法。无需使用任何骚操作(如1个元素的数组)。如果需要在类与其外部类之间进行任何数据交换,则我认为这种方式更干净。但我承认这是个人喜好。 1个元素的数组习惯用法也可以工作,而且更加简洁,但坦率地说,它看起来很难看。我通常将匿名内部类限制为仅执行操作而不尝试更新外部类中的数据的情况。例如:
private MyListener listener = new MyListener();

void onStart(){
  bt.setOnClickListener(listener);
}

class MyListener implements OnClickListener
{ 
    String name;
    int value;

    void setName(String newName)
    {
        name = newName;
    }

    void setValue(int newValue)
    {
        value = newValue;
    }

    public void onClick(View v) 
    {
        // Use the data for some unknown purpose
    }
}

如果涉及到多个线程,那么必须使用适当的同步。

赞。另一个好处是这个内部类更加可扩展和可重用。在我看来,匿名内部类几乎总是不明智的选择。 - user949300
它们作为一次性操作样式的类很有效,可以处理特定事件的处理程序,在这些事件中,根据输入执行操作。这在GUI编程中非常常见,这是他的例子。除了在这种情况下,类之间存在相互作用,使事情变得更加复杂。 - Robin

2

我在这里的另一个帖子中发布了类似的答案。基本上,想法是创建一个“包装器”,它可以包装几乎任何Object类型。由于Java中的final表示“不可重新分配”而不是“常量”,因此这个技巧基本上可以正常工作。但是,如原始帖子所提到的,确保在多线程环境中使用时要小心。


0

我建议您在外部类中保留对单击侦听器的引用,并将 int 声明为侦听器的成员变量。只需在侦听器单击时存储变量,需要时在外部类中获取变量,而不是在点击点设置变量。

简单来说,如果内部类需要更改它,则将其声明为内部类的变量。


0

根据评论中的内容,由于您似乎要设置多个事项,请在主类中创建一个方法button1WasClicked()(更好的名称可能是doUpdate、doSave等——与按钮功能相关的名称),将适当的代码放在其中,并从内部类/监听器中调用它。(如果您正在使用Swing,则可以将其作为Action,具体情况视情况而定)

这样,如果以后需要执行相同的操作,例如菜单、意图或手势,就可以直接调用该方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接