java - 匿名类中的非最终非局部变量

标签 java closures anonymous-class

据我了解,Java 没有真正的闭包。您可以通过 chaperoning 传递函数他们同一个类(class);然而,它不仅冗长而且(由于 Java 的内存模型)匿名类中对在构造它的环境中定义的变量的任何引用都作为 副本 传递。该语言通过仅允许匿名类引用 final 变量来鼓励我们记住这一点。

这让我想到了我在 Bloch 的 Effective Java 中找到的代码片段:

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 变量(并且不是简单的副本)那么我们这里似乎有一个闭包。约书亚布洛赫还表示,该程序在他的计算机上永远循环。但是我的运行了大约一秒钟就退出了。

我误解了内存模型的哪一部分?

最佳答案

您缺少的关键是匿名类是嵌套类。因此,它具有对包含类实例的隐式引用,因此也是该类的成员。

只有局部变量需要final才能被匿名类使用。

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

相关文章:

c++ - 如何将模板类限制为仅具有类型别名的特定专业

Java 包与其他包位于单独的存储库中

java - JSF 语言环境异常

java - 正则表达式帮助而不是java中的分割

javascript - 你知道有哪些视频教程完全专注于 JavaScript 中的闭包吗?

ios - 将现有函数作为参数传递给 Swift 3 中的另一个函数

java - 从内部匿名 Runnable 访问外部变量

java - 删除Java中二叉搜索树的方法实现?

c# - 如何|封闭变量存储在哪里?

java - 匿名类在 Java 中有何用处?