Java-8のメソッドリファレンスとジェネリックス


11

ジェネリック型と組み合わせたメソッド参照に関する問題に直面しています。

オーバーロードされたメソッドを呼び出す必要があるコードがありますが、エラーで失敗します:

値m1()を解決できません

問題がどこにあるのかを明確にするために、問題を単純化しました。

次のコードは失敗します。

public class Test {
    void test() {
        // Getting error here
        setValue(C1::m1, Integer.ONE);
    }

    <E extends I1, T> void setValue(BiConsumer<E, T> cons, T value) {
    }
}

interface I1 {
}

class C1 implements I1 {
    void m1(Integer value) {
    }

    void m1(int value) {
    }
}

なぜこれがこのように動作しているのか誰かが喜んでくれますか?

親切に、これはジェネリック型のJava 8メソッドリファレンスの質問とは関係ありません。


いいえ、それが正常に機能しているメソッドの1つを削除した場合
Joker

この質問をもう一度開いてくれてありがとう... :)
Joker

回答:


7

型推論規則は、適切なm1バリアントの選択とsetValue呼び出しへの正しい推論型パラメーターの生成(BおよびBigDecimalそれぞれ)の間の競合を解決するのに十分な「スマート」ではないようです。

これが失敗する理由を完全に説明することはできませんが、型推論は伝統的に難解で、合理的で直感的でないルールの領域でしたので、私はあまり驚いていません。

setValueコンパイラーが正しいm1メソッドを選択する時点で、タイプウィットネス(呼び出すタイプパラメーターを指定)を追加することで、この問題を回避できます。

this.<B,BigDecimal>setValue(B::m1, BigDecimal.ONE);

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.