2016-07-02 8 views
-1

Lassen Sie uns sagen, dass ich diese Funktion haben:Warum erlaubt Java keine generische Super-Typumwandlung, erlaubt sie aber über einen Platzhalter?

Table<Record> tableOfRecord() {} 

Und ein Typ TableRecord<R extends TableRecord> extends Record. Und ich habe diese andere Funktion:

<R extends TableRecord<R>> Table<R> table(Table<R> table, String filtered) { 
    // ... 
    return (Table<R>) tableOfRecord(); 
} 

Die oben zu kompilieren fehlschlägt:

error: incompatible types: Table<Record> cannot be converted to Table<R> 

Dies ist jedoch kompiliert und läuft gut:

return (Table<R>) ((Table<?>) tableOfRecord()); 

Ich bin nicht sicher, warum dies erlaubt ist , aber das vorherige Beispiel ist nicht.

+0

Ich weiß es nicht. Aber keines ist semantisch korrekt, AFAICS - eine 'Tabelle ' ist keine 'Tabelle ', es sei denn 'R' ist' Record', was hier unmöglich ist. –

+1

Sehen Sie sich die Warnungen Ihres Compilers an. Es ruft "unkontrollierte Besetzung". > was du machst ist fast gleichbedeutend mit 'return (Integer) ((Objekt)" Hallo ");' http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why -arent-javas-generics-implicitly-p –

+0

Die meisten generischen Informationen werden zur Laufzeit gelöscht. Die JVM sieht eine Umwandlung von '' Table''' zu '' Table''' und kann nicht bestätigen, dass diese Umwandlung tatsächlich typsicher ist (was sie tatsächlich nicht ist). Daher die ungeprüfte Zauberwarnung, die Sie beim Generieren von Generika erhalten. –

Antwort

0

Es ist illegal, Table<Record>-Table<R> zu werfen, weil es bei der Kompilierung nachgewiesen werden kann, dass kein Objekt sein kann sowohl Table<Record> und Table<R>, und somit wird die gegossene falsch sein garantiert. Es ist illegal, einen Cast zu schreiben, der sich zur Kompilierzeit als inkorrekt erweist.

(Table<R>)(Table<?>)tableOfRecord() ist eine Folge von zwei getrennten Abgüsse, einem von Typ Table<Record>-Table<?> und einem Table<?>-Table<R>, von denen jedem legal ist, weil jede Besetzung, von selbst, wird nicht zur Compile-Zeit als falsch bekannt.

Verwandte Themen