为什么 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/