Los genéricos de Java, el tipo se pierde

Andrey Sh:

En el siguiente ejemplo, aunque aparentemente correcta, no se compilará (Eclipse de neón 3, Java 1.8):

class Test {    

    public static class SomeForm<IF extends SomeForm<IF>> {

    }

    public static class BaseFF<IF extends SomeForm<IF>> {

    }

    public static class AuxFF<IF extends SomeForm<IF>>
            extends BaseFF<IF> {

    }

    public interface Interface<IF extends SomeForm<IF>, FF extends BaseFF<IF>> {
        FF getFF1();        
    }

    public static class ZBaseUnit<IF extends SomeForm<IF>, FF extends BaseFF<IF>>
            implements Interface<IF, FF> {

        @Override
        public FF getFF1() {
            return null;
        }

    }

    public static class ZMyUnit<IF extends SomeForm<IF>, FF extends AuxFF<IF>>
            extends ZBaseUnit<IF, FF> {

    }

    public static class ZMyCheck<IF extends SomeForm<IF>, U extends ZMyUnit<IF, ?>> {
        U unit;

        void f() {
            BaseFF<IF> ff1 = unit.getFF1();
        }

    }

}

Eclipse dice (en el método de la línea dentro de f ()):

"No coinciden los tipos: no se puede convertir de captura # 2 de a Test.BaseFF?".

Sin embargo, si quito los getFF1 método desde la interfaz Interface (y la anotación @ Override en el ZBaseUnit clase), que se compila. ¿Hay alguna lógica detrás de esto? Intuitivamente, parece que FF pasó a la interfaz es la misma que FF pasó a ZBaseUnit, por lo que no debería haber ninguna diferencia ...

Además, no hay ningún error si añado el método de ZMyUnit:

void f() {
    BaseFF<IF> ff1 = getFF1();
}

¡Cualquier ayuda sería apreciada!

John McClane:

Si se agrega el código de verificación para que la clase

public static class GF extends SomeForm<GF> {
}

public static void main(String[] args) {
    ZMyCheck<GF, ZMyUnit<GF, AuxFF<GF>>> z = new ZMyCheck<>();
    z.unit = new ZMyUnit<>();
    z.f();
    System.out.println("OK");
}

y el uso de herramientas JDK de línea de comandos estándar ( javacy java), entonces el código se compila y ejecuta con éxito. Lo mismo es cierto si se utiliza NetBeans (no tengo intención de promover NetBeans de ninguna manera).

Por lo tanto, el problema es Eclipse-específica. Eclipse tiene su propio compilador incorporado y parece que has encontrado una de sus debilidades (tal vez usted tiene que presentar un informe de error). Es incapaz de determinar que el comodín ?es, de hecho, refiriéndose al tipo que se extiende AuxFF<IF>(y, por lo tanto, BaseFF<IF>). Es necesario indicar de forma explícita:

public static class ZMyCheck<IF extends SomeForm<IF>,
    U extends ZMyUnit<IF, ? extends AuxFF<IF>>> {...}

Entonces todo compilar y ejecutar las mil maravillas.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=188748&siteId=1
Recomendado
Clasificación