a3.*_*ity 6 java heap lambda reference
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);
Run Code Online (Sandbox Code Playgroud)
在第 4 行,obj 是一个引用,它引用堆上的对象,它是通过调用 MyClass() 构造的。在第 5 行中,myComparator 是一个引用,它指的是赋值运算符另一侧的内容,即 Lambda 表达式。
Lambda 表达式是一个对象吗?如果是,它是否存储在堆上?它是否遵守垃圾收集器的规则,清理未引用的对象,或者它的行为略有不同?
如果不是,即如果 Lambda 表达式不是一个对象,从而假设它不存在于堆中,那么 myComparator(作为一个引用,假设它存在于堆栈中)如何能够引用一个 lambda 表达式并且我们能够调用一个方法呢?
在 Java 中,数组存储在堆上,我们可以安全地声明下面的数组也存储在堆上吗?我们可以安全地假设“可以运行的代码”作为对象存储在堆上吗?
FileFilter myFileFilter[] = new FileFilter[] {
f -> f.exists(), f -> f.canRead(), f -> f.getName().startsWith("q")
}
Run Code Online (Sandbox Code Playgroud)如果 Lambda 表达式可以被视为一个对象,我们是否可以将这个对象序列化并传输到另一个 JVM,从而允许在运行时将“可执行”代码从一个 JVM 发送到另一个 JVM?这将允许“接受”来自系统 A 的逻辑以在系统 B 上执行该逻辑。顺便说一句,将“代码”分发到其他系统可能成为可能(类似于序列化可运行线程并发送)?我的想法是否正确,请澄清这些是否已经存在。谢谢(有兴趣查看一些实现细节)
来自 JLS 第 15.27 节:
lambda 表达式的求值会生成函数接口的实例
所以 lambda 是对象(至少现在是这样)。因为 lambda 也不例外,所以 lambda 被像其他对象一样对待并存储在堆上。
如果我没记错的话,lambda 的实现方式(实际的 lambda 代码是在运行时生成的)可以允许它们的表示随着 JVM 的变化而变化,所以这在将来可能会改变。例如,无状态 lambda 可以使用用于实现值类型的功能,并且可能最终位于与“常规”堆不同的特殊内存区域中。
此实现允许使用一种有趣的方式来序列化 lambda:序列化生成 lambda 所需的内容而不是生成的代码本身。这使得 lambda 的发展相对独立于它们最初创建的 JVM,并且比固定的机器指令流更加灵活。
至于你的最后一个问题,你不知道,也不可能真正知道。“标准”答案是,是的,它们将位于堆上,因为数组和 lambda 是对象,但如果编译器可以将本地创建的数组(和其他对象)优化为堆栈实体,我不会感到惊讶。但不知道这种转变是否可能/可行/实施。
| 归档时间: |
|
| 查看次数: |
1049 次 |
| 最近记录: |