Lambda 和内存利用率

由于 Java lambda 是闭包,它们可以捕获封闭词法范围中的变量值。虽然并非所有 lambdas 都能捕获任何东西 - 像 s -> s.length() 这样的简单 lambda 只能捕获并且被称为无状态 - 捕获 lambdas 需要一个临时对象来保存捕获的变量。在此代码片段中,lambda () -> j 是一个捕获 lambda,并且可能导致在评估对象时分配对象:

public static void main(String[] args) throws Exception {
    for (int i = 0; i < 1000000000; i++) {
        int j = i;
        doSomethingWithLambda(() -> j);
    }
}

尽管由于 new 关键字没有出现在代码段中的任何位置,因此可能不会立即明显,但此代码可能会创建 1,000,000,000 个单独的对象来表示 () -> j lambda 表达式的实例。但是,还应该注意的是,Java 1 的 未来版本可能能够对其进行优化,以便在运行时重用 lambda 实例,或以其他方式表示。

1 - 例如,Java 9 为 Java 构建序列引入了一个可选的链接阶段,这将提供进行这样的全局优化的机会。