koz*_*zmo 7 java lambda equals functional-interface method-reference
我有两种生产“消费者”的工厂方法使用不同的方法 lambda 和方法引用:
@SuppressWarnings("Convert2MethodRef")
public Consumer<String> lambdaPrintStringConsumer(){
return x -> System.out.println(x);
}
public Consumer<String> methodRefPrintStringConsumer(){
return System.out::println;
}
Run Code Online (Sandbox Code Playgroud)
我发现在第一种情况 ( lambdaPrintStringConsumer()) 中,方法返回对同一对象的引用
@Test
public void shouldSameFromFactoryMethod_lambda() {
Consumer<String> consumerA = lambdaPrintStringConsumer();
Consumer<String> consumerB = lambdaPrintStringConsumer();
Assert.assertSame(consumerA, consumerB);//consumerA == consumerB --> true
}
Run Code Online (Sandbox Code Playgroud)
但是在第二个 ( methodRefPrintStringConsumer()) 中,对象是不同的
@Test
public void shouldNotSameFromFactoryMethod_methodRef() {
Consumer<String> consumerA = methodRefPrintStringConsumer();
Consumer<String> consumerB = methodRefPrintStringConsumer();
Assert.assertNotSame(consumerA, consumerB);//consumerA == consumerB --> false
}
Run Code Online (Sandbox Code Playgroud)
直接方法返回与以下相同的结果shouldNotSameFromFactoryMethod_methodRef():
@SuppressWarnings("Convert2MethodRef")
@Test
public void shouldNotSameFromLambda() {
Consumer<String> consumerA = s -> System.out.println(s);
Consumer<String> consumerB = s -> System.out.println(s);
Assert.assertNotSame(consumerA, consumerB);//consumerA == consumerB --> false
}
Run Code Online (Sandbox Code Playgroud)
,接下来我用方法引用其他静态方法测试了工厂方法
public class FunctionalInterfaceTest {
public static Consumer<String> methodRefFromStaticMethodStringConsumer() {
return FunctionalInterfaceTest::print;
}
public static void print(String string) {
System.out.println(string);
}
...
}
Run Code Online (Sandbox Code Playgroud)
并获得与第一个测试 ( lambdaPrintStringConsumer)相同的结果:
@Test
public void shouldSameFromFactoryMethod_methodRef() {
Consumer<String> consumerA = methodRefFromStaticMethodStringConsumer();
Consumer<String> consumerB = methodRefFromStaticMethodStringConsumer();
Assert.assertSame(consumerA, consumerB );//consumerA == consumerB --> true
}
Run Code Online (Sandbox Code Playgroud)
诀窍是什么?
在测试 jdk-11.0.1和jdk-13.0.1.
以下表达式是否等价?
x -> System.out.println(x)
System.out::println
Run Code Online (Sandbox Code Playgroud)
不。如果你打电话 System.setOut,前者会接新的PrintStream;后者不会。
所以,在这种情况下,lambda 方法不需要从封闭的词法范围访问变量,而这个方法引用表达式需要。这允许前者共享,但后者不能。
可能会或可能不会指定确切的细节 - 我懒得看。
| 归档时间: |
|
| 查看次数: |
261 次 |
| 最近记录: |