ファクトリメソッドとメソッドリファレンス(シングルトン/プロトタイプ)でラムダを使用すると、関数型インターフェイスの初期化が異なる理由

コスモ:

「コンシューマー」を生成する2つのファクトリーメソッドがあり、異なるアプローチを使用しています=>ラムダとメソッドリファレンス:

@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
}

2番目(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.1、とを使用しましたjdk-13.0.1

トム・ホーティン-タックライン:

次の式は同等ですか?

x -> System.out.println(x)

System.out::println

いいえ。電話をかけるSystem.setOutと、前者が新しいものを受け取りPrintStreamます。後者はしません。

したがって、この場合、ラムダメソッドは囲み字句スコープからの変数へのアクセスを必要としませんが、このメソッド参照式は必要です。これにより、前者は共有できますが、後者は共有できません。

正確な詳細が指定されている場合と指定されていない場合があります-わざわざ見る必要はありません。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ