java - Thread 的 run() 方法中的最终枚举

标签 java multithreading enums final

为什么 Elvis elvis 定义必须是最终的才能在 Thread run() 方法中使用?

 Elvis elvis = Elvis.INSTANCE; // ----> should be final Elvis elvis = Elvis.INSTANCE
 elvis.sing(4);

 Thread t1 = new Thread(
   new Runnable() {
   @Override
   public void run() {
   elvis.sing(6); // --------> elvis has to be final to compile
  }
}
);


 public enum Elvis {
   INSTANCE(2);

   Elvis() {
     this.x = new AtomicInteger(0);
   }

   Elvis(int x){
     this.x = new AtomicInteger(x);
   }

   private AtomicInteger x = new AtomicInteger(0);

   public int getX() { return x.get(); }

   public void setX(int x) {this.x = new AtomicInteger(x);}

   public void sing(int x) {
      this.x = new AtomicInteger(x);
      System.out.println("Elvis singing.." + x);
   }
 }

最佳答案

elvis 变量的值被匿名内部类捕获。

(当前)仅 Java 按值捕获变量。编译器要求该变量是最终变量,以便在新线程中调用 run 方法时不会混淆实际使用的内容:如果您更改了 elvis< 的值 在创建新线程之后但在启动它之前,您希望它做什么?

这是 C# 和 Java 中闭包有效使用方式之间的差异。看我的closures article了解更多详情。 Java 7 将使闭包更加简洁 - 我一直没有关注是否有任何方法可以捕获变量本身而不是特定值。

关于java - Thread 的 run() 方法中的最终枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2532798/

相关文章:

java - 重定向到新 URL 时小程序崩溃

swift - 我可以安全地将 NSManagedObject 传递给 performBackgroundTask 吗?

typescript - 自动字符串枚举

java - 调用 super 构造函数时尝试资源

java - 如何在phonegap中拼接照片和音频文件

java - 在firebase中更新数据时如何更新 TextView

java - GWT 2.6 和 jdk 1.6 出现 UnsupportedClassVersionError

c++ - 为什么有些线程会延迟?

c# - 如何从枚举类型的名称和 int 中获取枚举名称

c# - 保存和解析枚举集合的最快方法?