¿Por qué Eclipse compilar esto, pero javac no lo hace?
-
19-09-2019 - |
Pregunta
Tenemos algunas pruebas unitarias que compilar y ejecutar bien en Eclipse 3.4, pero cuando tratamos de compilar usando javac, falla. He conseguido reducir el código a algo pequeño y autónomo, por lo que no tiene dependencias externas. El código en sí no tiene mucho sentido porque es todo fuera de contexto, pero eso no importa - sólo hay que averiguar por qué javac no le gusta esto:
public class Test {
public void test() {
matchOn(someMatcher().with(anotherMatcher()));
}
void matchOn(SubMatcher matcher) {}
SubMatcher someMatcher() {
return new SubMatcher();
}
Matcher anotherMatcher() {
return null;
}
}
interface Matcher <U, T> {}
class BaseMatcher implements Matcher {
public BaseMatcher with(Matcher<?,?> matcher) {
return this;
}
}
class SubMatcher extends BaseMatcher {
@Override
public SubMatcher with(Matcher matcher) {
return this;
}
}
He tratado con JDK 1.5.0_10
y 1.6.0_13
, con el mismo resultado:
Test.java:6: matchOn(test.SubMatcher) in test.Test cannot be applied to (test.BaseMatcher)
matchOn(someMatcher().with(anotherMatcher()));
^
1 error
Creo que esto es perfectamente válido de Java. El método SubMatcher.with () devuelve un tipo más específico que BaseMatcher.with (), pero el compilador parece pensar que el tipo de retorno es BaseMatcher. Sin embargo, es posible que el compilador de Eclipse está permitiendo incorrectamente algo que no debería ser.
¿Alguna idea?
Solución
en BaseMatcher es necesario especificar los parámetros de tipo:
public SubMatcher with(Matcher<?, ?> matcher) {
con el fin de permitir que javac para que coincida con su método de with
PS
mi humilde opinión es un error del compilador Eclipse
Otros consejos
Lo hice construir con éxito mediante la adición de <?,?>
a Matcher
en SubMatcher.with
:
class SubMatcher extends BaseMatcher {
@Override
public SubMatcher with(Matcher<?,?> matcher) {
return this;
}
}
Sin esto, la firma del método es diferente de la base. Me pregunto si hay un error en la comprobación de @Override
que no se da cuenta de esto.
Comprobar el cual JRE o JDK está compilando con tanto en Eclipse y terminal. Tal podría ser el tema de versión.
A mí me funciona:
$ java -version openjdk version "1.7.0-internal" OpenJDK Runtime Environment (build 1.7.0-internal-****-2009_07_23_10_21-b00) OpenJDK 64-Bit Server VM (build 16.0-b06, mixed mode) $ javac -XDrawDiagnostics Test.java $
Recuerdo vagamente un informe de error tal, pero no puedo darle un enlace a ella en este momento.