Methodenreferenz und Generika in Java-8

11

Ich habe Probleme mit der Methodenreferenz in Kombination mit generischen Typen.

Wir haben Code, in dem wir eine überladene Methode aufrufen müssen, aber sie schlägt mit einem Fehler fehl:

Wert m1 () kann nicht aufgelöst werden

Ich habe mein Problem vereinfacht, um klar zu machen, wo das Problem liegt.

Der folgende Code schlägt fehl:

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

Kann jemand bitte, warum sich das so verhält?

Bitte beachten Sie, dass dies nicht mit der Frage der Java 8-Methodenreferenz mit generischen Typen zusammenhängt

Joker
quelle
Nein, wenn ich eine der Methoden entferne, funktioniert es gut
Joker
Vielen Dank, dass Sie diese Frage erneut geöffnet haben ... :)
Joker

Antworten:

7

Es scheint , dass die Typinferenz Regeln sind nicht „smart“ genug , um den Konflikt zwischen Kommissionierung das Recht zu lösen m1Variante und zum Erzeugen der richtigen abgeleiteten Typ Parameter an den setValueAufruf ( Bund BigDecimaljeweils).

Ich kann nicht genau erklären, warum dies fehlschlägt, aber die Typinferenz war traditionell ein Bereich mit arkanen, gut begründeten und nicht intuitiven Regeln, daher bin ich nicht sehr überrascht.

Sie können dieses Problem umgehen, indem Sie einen Typzeugen hinzufügen (der angibt, mit welchen Typparametern Sie aufrufen möchten setValue). An diesem Punkt wählt der Compiler die richtige m1Methode aus:

this.<B,BigDecimal>setValue(B::m1, BigDecimal.ONE);
Joachim Sauer
quelle
Scheint, ich bin nicht im Einklang mit docs.oracle.com/javase/specs/jls/se8/html/…
Joker