JVM 什么时候决定重用旧的 lambda?

2022-01-16 00:00:00 lambda jvm java-8 java

考虑以下代码片段:

public static Object o = new Object();

public static Callable x1() {
    Object x = o;
    return () -> x;
}

public static Callable x2() {
    return () -> o;
}

方法 x2() 将始终返回相同的 Lamba 对象,而 x1() 将始终创建新对象:

Method x2() will always return the same lamba object, while x1() will always create new one:

    System.out.println(x1());
    System.out.println(x1());
    System.out.println(x2());
    System.out.println(x2());

会打印出如下内容:

TestLambda$$Lambda$1/821270929@4a574795
TestLambda$$Lambda$1/821270929@f6f4d33
TestLambda$$Lambda$2/603742814@7adf9f5f
TestLambda$$Lambda$2/603742814@7adf9f5f

在哪里(我猜是在 JVM 规范中?)描述了这个 lambda 重用规则?JVM如何决定在哪里重用?

Where (in JVM specification I guess?) is this rule of lambda reuse described? How does JVM decide where do reuse or not?

推荐答案

您无法确定为 lambda 表达式返回的对象的身份.它可以是新实例,也可以是预先存在的实例.

You can't be sure about the identity of the object returned for a lambda expression. It can be a new instance, or a pre-existing instance.

这在 中指定JLS §15.27.4:

在运行时,对 lambda 表达式的求值类似于对类实例创建表达式的求值,只要正常完成产生对对象的引用.lambda 表达式的求值不同于 lambda 主体的执行.

At run time, evaluation of a lambda expression is similar to evaluation of a class instance creation expression, insofar as normal completion produces a reference to an object. Evaluation of a lambda expression is distinct from execution of the lambda body.

要么分配并初始化具有以下属性的类的新实例,要么引用具有以下属性的类的现有实例.如果要创建一个新实例,但没有足够的空间来分配对象,则 lambda 表达式的计算会通过抛出 OutOfMemoryError 突然完成.

Either a new instance of a class with the properties below is allocated and initialized, or an existing instance of a class with the properties below is referenced. If a new instance is to be created, but there is insufficient space to allocate the object, evaluation of the lambda expression completes abruptly by throwing an OutOfMemoryError.

相关文章