在 Java 中,我们可以声明 lambda 表达式存储在堆中吗?

In Java, can we claim that lambda expressions are stored and is present in heap?

1. public interface MyComparator {
2.    public boolean compare(int a1, int a2);
3. }
4. MyClass obj = new MyClass();
5. MyComparator myComparator = (a1, a2) -> return a1 > a2;
6. boolean result = myComparator.compare(2, 5);

在第 4 行中,obj 是指向堆上对象的引用,它是通过调用 MyClass() 构造的。 在第 5 行中,myComparator 是一个引用,它指的是 赋值运算符的另一侧存在什么,即 Lambda 表达式。

来自 JLS 第 15.27 节:

Evaluation of a lambda expression produces an instance of a functional interface

所以 lambda 是对象(至少现在是这样)。因为 lambda 也不例外,所以 lambda 被当作其他对象一样对待并存储在堆上。

如果我没记错的话,lambda 的实现方式(实际的 lambda 代码是在运行时生成的)允许它们的表示随着 JVM 的变化而变化,所以这在未来可能会发生变化。例如,无状态 lambda 可以使用用于实现值类型的特性,并且可能最终位于不同于 "regular" 堆的特殊内存区域。

此实现允许一种有趣的方式 serializing a lambda:序列化生成 lambda 所需的内容而不是生成的代码本身。这让 lambda 相对独立于最初创建它们的 JVM 发展,并且比固定的机器指令流灵活得多。

关于你最后一个问题,你不知道也不可能知道。 "standard" 答案是肯定的,它们将在堆上,因为数组和 lambda 是对象,但如果编译器可以将本地创建的数组(和其他对象)优化为堆栈实体,我不会感到惊讶。不过,不知道该转换是否为 possible/feasible/implemented。