2009-07-24 18 views
7

Wir haben einige Komponententests, die kompilieren und in Eclipse 3.4 funktionieren, aber wenn wir versuchen, sie mit javac zu kompilieren, schlägt es fehl. Ich habe es geschafft, den Code auf ein kleines und eigenständiges Programm zu reduzieren, so dass es keine externen Abhängigkeiten gibt. Der Code selbst wird nicht viel Sinn machen, weil es alles aus dem Zusammenhang gerissen ist, aber das macht nichts - ich muss nur herausfinden, warum Javac dies nicht mag:Warum kompiliert Eclipse dies, aber Javac nicht?

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; 
    } 
} 

ich mit JDK 1.5.0_10 versucht haben, und 1.6.0_13, mit dem gleichen Ergebnis:

Test.java:6: matchOn(test.SubMatcher) in test.Test cannot be applied to (test.BaseMatcher) 
       matchOn(someMatcher().with(anotherMatcher())); 
       ^
1 error 

ich denke, das absolut gültiges Java ist. Die SubMatcher.with() -Methode gibt einen spezifischeren Typ als BaseMatcher.with() zurück, aber der Compiler scheint zu denken, dass der Rückgabetyp BaseMatcher ist. Es ist jedoch möglich, dass der Eclipse-Compiler fälschlicherweise etwas zulässt, was nicht sein sollte.

Irgendwelche Ideen?

+1

Ich kann diesen Compiler-Fehler mit jdk 1.6 unter Linux reproduzieren. Scheint, dass die kovarianten Rückgabetypen, die mit Java 1.5 eingeführt wurden, in diesem Beispiel nicht korrekt funktionieren. – Mnementh

Antwort

7

in BaseMatcher müssen Sie Typparameter angeben:

public SubMatcher with(Matcher<?, ?> matcher) { 

um javac zu ermöglichen, Ihre with Methode

PS

imho ist ein Fehler von Eclipse-Compiler übereinstimmen

+0

Ach, ich kann nicht glauben, dass ich das nicht bemerkt habe .... – skaffman

+0

Du selbst und Greg haben beide die Antwort, aber ich muss den Preis jemandem geben, und du warst etwas schneller ... – skaffman

0

Überprüfen Sie, mit welchem ​​jre oder jdk Sie sowohl auf Eclipse als auch auf dem Terminal kompilieren. Vielleicht könnte es das Versionsproblem sein.

+0

Eclipse verwendet das 1.5.0_10 JRE, dasselbe wie das Javac, das ich versuche. – skaffman

+0

Eclipse hat seinen eigenen Compiler, dh es verwendet nicht javac – robinr

0

Works für mich:

 
$ 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 
$ 

Ich erinnere mich vage an einen solchen Bugreport, kann Ihnen aber im Moment keinen Link dazu geben.

class SubMatcher extends BaseMatcher { 
    @Override 
    public SubMatcher with(Matcher<?,?> matcher) { 
     return this; 
    } 
} 

Ohne dies die Methodensignatur unterscheidet sich von der Basis:

7

I durch Zugabe zu <?,?>Matcher in SubMatcher.with erfolgreich aufzubauen hergestellt. Ich frage mich, ob es einen Fehler in der @Override Überprüfung gibt, die dies nicht bemerkt.

+3

Das ist eine interessante Situation. Sie könnten argumentieren, dass hier der Fehler javac vorliegt, da die Annotation @Override zulässig ist, aber dann die Subklassenmethode und nicht die überschriebene Methode verwendet wird. Das ist inkonsistent, die Annotation soll diese Art von Problem verhindern. Die Frage ist, ob eine Methode mit einem Raw-Typparameter eine Superklassenmethode vom selben Typ mit überschreiben kann – skaffman

Verwandte Themen