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!
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 ( javac
y 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.