Ссылка на метод и обобщение в 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 с универсальными типами

джокер
источник
нет, если я уберу один из методов, он будет работать нормально
Джокер
Спасибо за то, что снова
Джокер

Ответы:

7

Кажется, что правила вывода типов недостаточно «умны», чтобы разрешить конфликт между выбором правильного m1варианта и генерацией правильных выведенных параметров типа для setValueвызова ( Bи BigDecimalсоответственно).

Я не могу полностью объяснить, почему это не удается, но вывод типов традиционно был областью с загадочными, аргументированными и неинтуитивными правилами, поэтому я не очень удивлен.

Вы можете обойти эту проблему, добавив свидетеля типа (указав параметры типа, которые вы хотите вызвать setValue), и в этот момент компилятор выберет правильный m1метод:

this.<B,BigDecimal>setValue(B::m1, BigDecimal.ONE);
Йоахим Зауэр
источник
Кажется, я не согласен
Джокер