Referencia de métodos y genéricos en Java-8

11

Estoy enfrentando un problema con la referencia de método combinada con tipos genéricos.

Tenemos un código donde necesitamos llamar a un método sobrecargado, pero falla con un error:

No se puede resolver el valor m1 ()

He simplificado mi problema para aclarar dónde está el problema.

El siguiente código falla:

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

¿Alguien puede por qué esto se comporta así?

Tenga en cuenta que esto no está relacionado con la pregunta Java 8 Método de referencia con tipos genéricos

bufón
fuente
no, si elimino uno de los métodos, funciona bien entonces
Joker
Gracias por reabrir esta pregunta nuevamente ... :)
Joker

Respuestas:

7

Parece que las reglas de inferencia de tipos no son lo suficientemente "inteligentes" como para resolver el conflicto entre elegir la m1variante correcta y generar los parámetros de tipo inferidos correctos para la setValuellamada ( By BigDecimalrespectivamente).

No puedo explicar por qué esto falla, pero la inferencia de tipos ha sido tradicionalmente un área con reglas arcanas, bien razonadas y poco intuitivas, por lo que no estoy muy sorprendido.

Puede solucionar este problema agregando un testigo de tipo (especificando con qué parámetros de tipo desea llamar setValue), momento en el cual el compilador elegirá el m1método correcto :

this.<B,BigDecimal>setValue(B::m1, BigDecimal.ONE);
Joachim Sauer
fuente
Parece que no estoy en línea con docs.oracle.com/javase/specs/jls/se8/html/…
Joker