Interesting question so I ran it through a decompiler - but the answer supports Andrew Tobilko answer
java -jar cfr_0_119.jar LambdaTest --decodelambdas false
/*
* Decompiled with CFR 0_119.
*/
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());
}
}
So the method reference is getting a copy of the first instance of x which is why it outputs "ONE" twice, and a static lambda isnt created, only a call to toUpper
I also ran the second example which does create a lambda(I missed out the part that doesnt compile -
java -jar cfr_0_119.jar LambdaTest --decodelambdas false
/*
* Decompiled with CFR 0_119.
*/
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 /* synthetic */ String lambda$0(String string) {
return string.toUpperCase();
}
}