这是一个有趣的问题,我运用反编译器进行了研究 - 但答案支持Andrew Tobilko的回答。
java -jar cfr_0_119.jar LambdaTest --decodelambdas false
import java.io.PrintStream;
import java.lang.invoke.LambdaMetafactory;
import java.util.function.Supplier;
public class LambdaTest {
public static void main(String[] args) {
String x = "one";
Supplier<String> s = (Supplier<String>)LambdaMetafactory.metafactory(null, null, null, ()Ljava/lang/Object;, toUpperCase(), ()Ljava/lang/String;)((String)x);
System.out.println("s.get() = " + s.get());
x = "two";
System.out.println("s.get() = " + s.get());
}
}
因此,方法引用获取的是 x 的第一个实例的副本,这就是为什么它会输出两次“ONE”的原因,而且不会创建静态 lambda,只会调用 toUpper。
我还运行了第二个示例,它确实创建了一个 lambda(我错过了不能编译的部分 -
java -jar cfr_0_119.jar LambdaTest --decodelambdas false
import java.io.PrintStream;
import java.lang.invoke.LambdaMetafactory;
import java.util.function.Supplier;
public class LambdaTest {
public static void main(String[] args) {
String y = "one";
Supplier<String> sy = (Supplier<String>)LambdaMetafactory.metafactory(null, null, null, ()Ljava/lang/Object;, lambda$0(java.lang.String ), ()Ljava/lang/String;)((String)y);
System.out.println("sy.get() = " + sy.get());
}
private static String lambda$0(String string) {
return string.toUpperCase();
}
}
Supplier
的东西,它会输出"TWO"。 - Bathsheba