Référence de méthode et génériques en Java-8

11

Je suis confronté à un problème de référence de méthode combinée à des types génériques.

Nous avons du code où nous devons appeler une méthode surchargée, mais il échoue avec une erreur:

Impossible de résoudre la valeur m1 ()

J'ai simplifié mon problème pour indiquer clairement où se situe le problème.

Le code suivant échoue:

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

Quelqu'un peut-il s'il vous plaît pourquoi cela se comporte comme ça?

Veuillez noter que cela n'est pas lié à la question Référence de la méthode Java 8 avec les types génériques

Joker
la source
non si je supprime l'une des méthodes, cela fonctionne bien alors
Joker
Merci d'avoir rouvert cette question à nouveau ... :)
Joker

Réponses:

7

Il semble que les règles d'inférence de type ne soient pas suffisamment «intelligentes» pour résoudre le conflit entre la sélection de la bonne m1variante et la génération des paramètres de type déduit corrects pour l' setValueappel ( Bet BigDecimalrespectivement).

Je ne peux pas tout à fait expliquer pourquoi cela échoue, mais l'inférence de type a toujours été un domaine avec des règles obscures, bien motivées et peu intuitives, donc je ne suis pas très surpris.

Vous pouvez contourner ce problème en ajoutant un témoin de type (en spécifiant les paramètres de type avec lesquels vous souhaitez appeler setValue) à quel point le compilateur choisira la bonne m1méthode:

this.<B,BigDecimal>setValue(B::m1, BigDecimal.ONE);
Joachim Sauer
la source
Semble que je ne suis pas en ligne avec docs.oracle.com/javase/specs/jls/se8/html/…
Joker