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

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表达式.

> Lambda Expression是一个对象吗?如果是,它是否存储在堆上?它是否符合垃圾收集器的规则,它清理未引用的对象或它的行为略有不同?
>如果不是,即如果Lambda Expression不是一个对象,从而假设它不存在于堆中,那么myComparator(作为一个引用,假设它存在于堆栈中)如何能够引用lambda表达式,我们是能够调用一个方法吗?
>在Java中,数组存储在堆上,我们可以安全地声称下面的数组也存储在堆上吗?我们能否安全地假设“可以运行的代码”被存储为堆上的对象?

FileFilter myFileFilter[] = new FileFilter[] { 
f -> f.exists(), f -> f.canRead(), f -> f.getName().startsWith("q") 
    }

>如果可以将Lambda表达式视为对象,我们是否可以序列化此对象并传输到另一个JVM,允许在运行时将“可执行”代码从一个JVM发送到另一个JVM?这将允许从系统A“接受”逻辑以在系统B上执行该逻辑.另外,可能有可能将“代码”分发给其他系统(类似于序列化可运行的线程并发送)?我正在思考正确的道路,请澄清这些是否已经存在的可能性.谢谢
(有兴趣看一些实施细节)

最佳答案 来自JLS第15.27节:

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

所以lambdas是对象(至少目前为止).因为lambda没有例外,所以lambda被视为与其他对象一样并存储在堆上.

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

这个实现允许serializing a lambda的有趣方式:序列化生成lambda所需的东西而不是生成的代码本身.这使得lambdas相对独立于它们最初创建的JVM而发展,并且比固定的机器指令流更灵活.

至于你的上一个问题,你不知道也不能真正知道. “标准”答案是肯定的,它们会在堆上,因为数组和lambda是对象,但如果编译器可以将本地创建的数组(和其他对象)优化为堆栈实体,我也不会感到惊讶.但是,不知道这种转变是否可行/可行/实施.

点赞