java - 克服匿名类中的最终变量

标签 java anonymous-inner-class

有没有办法克服在匿名内部类中访问的变量必须是最终变量这一事实?

例如,我有一个按钮可以随时报告列表的大小。在稍后的 while 循环中,list 应该被修改并且每个循环 list 将被新实例化,如果 list 是 final<,这是不可能的/p>

// has to be final
final ArrayList<String> list = new ArrayList<String>();

MyButton button = new MyButton() {
    @Override
    public int getValue() {
        return list.size();
    }
};

while (true) {
    // modify/re-assign list
}

实现此目的的一种方法是使 list 成为静态变量,但这不是最优的。还有其他方法可以克服这个问题吗?

最佳答案

没有,没有。

这不是可以克服的事情。由于访问字段变量的匿名类是闭包,因此字段变量的范围超出了原始声明的生命周期。

Java 实现这一点的方法是在匿名类中创建引用的本地副本。您可以将其视为等同于:

final ArrayList<String> list = new ArrayList<String>();

class MyButtonImpl extends MyButton {
     final ArrayList<String> list;

     public MyButtonImpl(final ArrayList<String> list) {
         this.list = list;
     }

}

MyButton button = new MyButtonImpl(list);

因此您可以看到 MyButtonImpl 中对 list 的引用是一个不同引用。在方法中重新分配引用不会影响 MyButtonImpl 中的引用。

出于这个原因,Java 不允许在匿名类中引用非(有效的)final 字段 - 它不会按预期运行。

至于处理你的具体问题,要么:

  • 不要重新分配list,只需使用clear();或
  • 像我所做的那样创建一个本地,并改用它的引用;或
  • 使用可变容器,例如 AtomicReference

最后一个建议是一个肮脏的 hack,但在一些罕见的情况下很有用。

关于java - 克服匿名类中的最终变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27997758/

相关文章:

java - 匿名内部类: declared as instance variables vs creating on the fly

java - 我如何确定是否使用 Spring jpa 插入或更新记录

java - 在java中获取USB调制解调器连接的com端口

java - BufferedWriter 仅保存文本文件中的最后输入

javafx 匿名应用程序类

java - 这两个匿名类的声明有什么区别

java - 访问匿名内部类中封闭范围的成员变量

c# - C#中的匿名内部类

java - (JTabbedPane) 与 Nimbus 不同,透明度在 L&F 上不起作用

java - Spring Security 在运行时注销用户