2013-07-26 7 views
5

Angenommen, ich habe dies:Casting auf generische Subtypen einer generischen Klasse

class Base<T> {} 

class Derived<T> extends Base<T> {} 

Dann in meinem Code, kann ich sicher ohne eine Warnung wie diese Stimmen:

public <T> void foo(Base<T> base) { 
    Derived<T> f = (Derived<T>) base; // fine, no warning 
} 

was in Ordnung ist. Wenn die abgeleitete Klasse jedoch mehr Typparameter hat, funktioniert sie nicht mehr:

class Base<T> {} 

class Derived<T, U> extends Base<T> {} 

public <T> void foo(Base<T> base) { 
    Derived<T, ?> f = (Derived<T, ?>) base; // unchecked warning! 
} 

Warum ist das? Gibt es etwas Offensichtliches, dass ich hier vermisse?

+0

Warum funktioniert es nicht? Es funktionierte für mich ... – m3th0dman

+0

Was "nicht funktioniert" ist, dass ich eine ungeprüfte Warnung bekomme, obwohl diese Besetzung vollkommen sicher ist. –

+0

Welcher Compiler? Ich sehe es mit dem Eclipse-Compiler. –

Antwort

5

Das scheint wie ein Fehler für mich. Von JLS §5.5.2. Checked Casts and Unchecked Casts:

Gegossener von einem Typ S auf einen parametrierten Typ (§4.5) T ist nicht markiert , wenn nicht mindestens eine der folgenden Bedingungen gilt:

  • S <: T

  • Alle der Typargumente (§4.5.1) von T sind unbegrenzt Platzhalter

  • T <: S a nd S hat kein Subtyp X anders als T, wo die Typargumente von X nicht in den Typargumente von T. enthalten

Angesichts Ihrer Typen Base<T> und Derived<T, ?> als S und T jeweils die ersten beiden Bedingungen halten eindeutig nicht an.

, dass die dritte Bedingung lässt - die nicht halten, wenn wir einen Subtyp von Base<T> andere als Derived<T, ?>, deren Typ Argumente identifizieren können, sind nicht in den Typargumente von Derived<T, ?> enthalten. Wenn die Warnung richtig ist, muss ein solcher Subtyp existieren, aber ich kann keinen identifizieren. Beispielsweise funktioniert Derived<?, ?> nicht, da es kein Subtyp Base<T> ist.

+0

Ich zögerte, diese Antwort zu posten, da der Eclipse-Compiler eine gute Erfolgsbilanz mit Generika hat. Wenn ich diese Warnung in Eclipse sehe, denke ich, dass mir etwas fehlt. Wenn ich die JLS falsch interpretiere, bitte kommentiere oder bearbeite meine Antwort für die Richtigkeit. –

+1

JDK 7 gibt keine Warnung aus. JLS 5/6 hat die Warnung nicht vorgeschrieben. Ich denke, jdt Compiler Entwickler verpasst die Änderung einfach oder ignoriert sie aufgrund des Fehlers (es sollte sein: "... kein Subtyp X anders als T wo ** | T | = | X | und ** ..." –

+0

@ BenSchulz Ja, ich habe mich selbst über diese Formulierung gefragt - gibt es dafür ein JLS-Problem? –