Java 8の::(ダブルコロン)演算子 質問する

Java 8の::(ダブルコロン)演算子 質問する

Java 8 のソースを調べていたところ、コードのこの部分が非常に驚くべきものであることがわかりました。

// Defined in IntPipeline.java
@Override
public final OptionalInt reduce(IntBinaryOperator op) {
    return evaluate(ReduceOps.makeInt(op));
}

@Override
public final OptionalInt max() {
    return reduce(Math::max); // This is the gotcha line
}

// Defined in Math.java
public static int max(int a, int b) {
    return (a >= b) ? a : b;
}

Math::maxメソッド ポインタのようなものですか? 通常のメソッドはどのようにして に変換されるの
でしょうか?staticIntBinaryOperator

ベストアンサー1

reduce通常、次のようにしてメソッドを呼び出しますMath.max(int, int)

reduce(new IntBinaryOperator() {
    int applyAsInt(int left, int right) {
        return Math.max(left, right);
    }
});

を呼び出すだけでも多くの構文が必要になりますMath.max。ここでラムダ式が役立ちます。Java 8 以降では、同じことをはるかに短い方法で実行できるようになりました。

reduce((int left, int right) -> Math.max(left, right));

これはどのように動作するのでしょうか? Java コンパイラは、 を 2 つ受け入れてint1 つを返すメソッドを実装しようとしていることを「検出」しますint。これは、インターフェースの唯一のメソッドの正式なパラメータIntBinaryOperator(呼び出したいメソッドのパラメータreduce) に相当します。そのため、コンパイラが残りの作業を行います。つまり、 を実装しようとしていると想定するだけですIntBinaryOperator

しかし、Math.max(int, int)自体は の形式要件を満たしているためIntBinaryOperator、直接使用できます。Java 7 には、メソッド自体を引数として渡すことを許可する構文がないため (メソッドの結果のみを渡すことができ、メソッド参照は渡すことができません)、メソッドを::参照するための構文が Java 8 で導入されました。

reduce(Math::max);

これは実行時に JVM ではなくコンパイラによって解釈されることに注意してください。3 つのコード スニペットすべてに対して異なるバイトコードが生成されますが、意味的には同じであるため、最後の 2 つはIntBinaryOperator上記の実装の短縮版 (おそらくより効率的なバージョン) と見なすことができます。

(参照ラムダ式の翻訳

おすすめ記事