Referensi metode dan Generik di Java-8

11

Saya menghadapi masalah dengan referensi metode yang dikombinasikan dengan tipe generik.

Kami memiliki kode tempat kami perlu memanggil metode kelebihan beban, tetapi gagal dengan kesalahan:

Tidak dapat menyelesaikan nilai m1 ()

Saya telah menyederhanakan masalah saya untuk memperjelas di mana masalahnya.

Kode berikut gagal:

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) {
    }
}

Bisakah seseorang tolong mengapa ini berperilaku seperti ini?

Mohon diperhatikan bahwa ini tidak terkait dengan pertanyaan referensi Metode Java 8 dengan tipe generik

Pelawak
sumber
tidak jika saya menghapus salah satu metode itu berfungsi dengan baik maka
Joker
Terima kasih telah membuka kembali pertanyaan ini lagi ... :)
Joker

Jawaban:

7

Tampaknya aturan inferensi jenis tidak "pintar" untuk menyelesaikan konflik antara memilih m1varian yang tepat dan menghasilkan parameter tipe inferensi yang tepat untuk setValuepanggilan ( Bdan BigDecimalmasing - masing).

Saya tidak bisa menjelaskan mengapa ini gagal, tetapi inferensi tipe secara tradisional merupakan area dengan aturan yang misterius, beralasan dan tidak intuitif, jadi saya tidak terlalu terkejut.

Anda dapat mengatasi masalah ini dengan menambahkan saksi tipe (menentukan parameter tipe mana yang ingin Anda panggil setValue) di titik mana kompiler akan memilih m1metode yang benar :

this.<B,BigDecimal>setValue(B::m1, BigDecimal.ONE);
Joachim Sauer
sumber
Sepertinya saya tidak sejalan dengan docs.oracle.com/javase/specs/jls/se8/html/…
Joker