gpt4 book ai didi

java - 为什么在工厂方法和方法引用(单例/原型(prototype))中使用 lambda 时功能接口(interface)初始化不同?

转载 作者:行者123 更新时间:2023-12-01 01:40:09 25 4
gpt4 key购买 nike

我有两种工厂方法生产 “消费者”使用不同的方法👉🏻 lambda 和方法引用:

@SuppressWarnings("Convert2MethodRef")
public Consumer<String> lambdaPrintStringConsumer(){
return x -> System.out.println(x);
}

public Consumer<String> methodRefPrintStringConsumer(){
return System.out::println;
}
我发现在第一种情况下( lambdaPrintStringConsumer() ),方法返回对同一对象的引用
@Test
public void shouldSameFromFactoryMethod_lambda() {
Consumer<String> consumerA = lambdaPrintStringConsumer();
Consumer<String> consumerB = lambdaPrintStringConsumer();

Assert.assertSame(consumerA, consumerB);//consumerA == consumerB --> true
}
但在第二个( methodRefPrintStringConsumer() )中,对象不同
@Test
public void shouldNotSameFromFactoryMethod_methodRef() {
Consumer<String> consumerA = methodRefPrintStringConsumer();
Consumer<String> consumerB = methodRefPrintStringConsumer();

Assert.assertNotSame(consumerA, consumerB);//consumerA == consumerB --> false
}
直接方法返回与 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
}
,接下来我用其他静态方法的方法引用测试了工厂方法
public class FunctionalInterfaceTest {

public static Consumer<String> methodRefFromStaticMethodStringConsumer() {
return FunctionalInterfaceTest::print;
}

public static void print(String string) {
System.out.println(string);
}

...

}
并获得与第一个测试相同的结果( lambdaPrintStringConsumer ):
@Test
public void shouldSameFromFactoryMethod_methodRef() {
Consumer<String> consumerA = methodRefFromStaticMethodStringConsumer();
Consumer<String> consumerB = methodRefFromStaticMethodStringConsumer();

Assert.assertSame(consumerA, consumerB );//consumerA == consumerB --> true
}
什么是 把戏
在测试中👉🏻 jdk-11.0.1jdk-13.0.1 .

最佳答案

以下表达式是否等价?

x -> System.out.println(x)

System.out::println

没有。如果您调用 System.setOut ,前者将拿起新的 PrintStream ;后者不会。

因此,在这种情况下,lambda 方法不需要从封闭的词法范围访问变量,而此方法引用表达式则需要。这允许前者被共享,但后者不能。

可能会或可能不会指定确切的细节-我懒得看。

关于java - 为什么在工厂方法和方法引用(单例/原型(prototype))中使用 lambda 时功能接口(interface)初始化不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58920215/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com