Perché Eclipse compilare questo, ma javac non lo fa?
-
19-09-2019 - |
Domanda
Abbiamo alcuni test di unità che compilare ed eseguire bene in Eclipse 3.4, ma quando si tenta di compilare utilizzando javac, fallisce. Sono riuscito a tagliare il codice fino a qualcosa di piccolo e indipendente, quindi non ha dipendenze esterne. Il codice di per sé non ha molto senso perché è tutto fuori contesto, ma questo non importa - ho solo bisogno di scoprire perché javac non piace questo:
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;
}
}
Ho provato con JDK 1.5.0_10
e 1.6.0_13
, con lo stesso risultato:
Test.java:6: matchOn(test.SubMatcher) in test.Test cannot be applied to (test.BaseMatcher)
matchOn(someMatcher().with(anotherMatcher()));
^
1 error
Credo che questo sia perfettamente valido Java. Il metodo SubMatcher.with () restituisce un tipo più specifico di BaseMatcher.with (), ma il compilatore sembra pensare che il tipo di ritorno è BaseMatcher. Tuttavia, è possibile che il compilatore Eclipse sta permettendo in modo errato qualcosa che non dovrebbe essere.
Tutte le idee?
Soluzione
in BaseMatcher è necessario specificare parametri di tipo:
public SubMatcher with(Matcher<?, ?> matcher) {
al fine di consentire javac per abbinare il vostro metodo di with
PS
IMHO è un bug di compilatore Eclipse
Altri suggerimenti
L'ho fatta costruire con successo con l'aggiunta di <?,?>
a Matcher
in SubMatcher.with
:
class SubMatcher extends BaseMatcher {
@Override
public SubMatcher with(Matcher<?,?> matcher) {
return this;
}
}
Senza questo, la firma del metodo è diverso dalla base. Mi chiedo se ci sia un bug nel controllo @Override
che non riesce a notare questo.
Controlla che JRE o JDK si sta compilando con su entrambi Eclipse e terminale. Forse potrebbe essere il problema di versione.
Lavora per me:
$ 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 $
Mi ricordo vagamente una tale bugreport, ma non si può dare un link ad esso al momento.