後者の読みやすさのわずかな改善以外に、次の構造の使用に違いはありますか?
someList.stream().map(item -> new NewClass(item)).collect(Collectors.toList());
someList.stream().map(NewClass::new).collect(Collectors.toList());
通常、違いはありません。 NewClass::new
は、ラムダバージョンの場合より少ないバイトコードを生成します。自動生成されたプライベートメソッドは、ラムダ本体からJavaコンパイラによって作成され、NewClass:new
はコンストラクタメソッドハンドルに直接リンクします。したがって、メソッド参照を使用すると、クラスファイルのサイズがわずかに小さくなる場合があります。ただし、パフォーマンスに大きな違いはありません。
もう1つの違いは、メソッド解決手順です。特定の例には適用されませんが、他のコードにも適用される場合があります。たとえば、2つのコンストラクターがあります。
public NewClass(String a) {...}
public NewClass(String a, String b) {...}
そして、機能的なインターフェイスを受け入れるいくつかのメソッドがあります:
public myMethod(Function<String, NewClass> fn) {...}
次に、ラムダまたは機能インターフェイスの両方で呼び出すことができます:
myMethod(str -> new NewClass(str));
myMethod(NewClass::new);
しかし、後で次のような同じ名前の新しいメソッドを追加するとします。
public myMethod(BiFunction<String, String, NewClass> fn) {...}
そうすると、メソッド参照呼び出しはあいまいになり、NewClass::new
が両方のコンストラクターに一致するため、コンパイルエラーが発生しますが、ラムダはまだあいまいではありません。