【发布时间】:2011-11-14 10:22:08
【问题描述】:
据我了解,Java 没有真正的闭包。你可以通过chaperoning他们用一个类来传递一个函数;然而,它不仅冗长而且(由于 Java 的内存模型)匿名类中对在构造它的环境中定义的变量的任何引用都作为副本传递。该语言通过只允许匿名类引用final 变量来鼓励我们记住这一点。
这让我想到了我在 Bloch 的 Effective Java 中找到的这段代码 sn-p:
import java.util.concurrent.*;
public class StopThread {
private static boolean stopRequested;
public static void main(String[] args)
throws InterruptedException {
Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
while (!stopRequested)
i++;
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
}
首先,我希望编译器会抱怨,因为stopRequested 是非最终的,我在匿名类中引用它。我的编译器没有抱怨。
其次,我希望程序永远循环,因为,Java 不支持闭包,如果匿名类真的是指来自它构造的环境中的实际 stopRequested 变量(而不是简单的副本)那么似乎我们在这里关闭了。 Joshua Bloch 还说程序在他的计算机上永远循环。但我的运行大约一秒钟然后退出。
我误解了内存模型的哪一部分?
【问题讨论】:
标签: java closures anonymous-class