2013-07-26 13 views
5

Załóżmy, że mam to:Casting do generycznych podtypów rodzajowego klasy

class Base<T> {} 

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

Wtedy w moim kodu, mogę bezpiecznie rzucać bez ostrzeżenia tak:

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

co jest w porządku. Ale jeśli klasa pochodna ma więcej parametrów typu, to już nie działa:

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

Dlaczego tak jest? Czy jest tu coś oczywistego, czego tu brakuje?

+0

Dlaczego to nie działa? To zadziałało dla mnie ... – m3th0dman

+0

To, co "nie działa", polega na tym, że dostaję niezaznaczone ostrzeżenie, chociaż ta obsada jest całkowicie bezpieczna. –

+0

Jaki kompilator? Widzę to z kompilatorem Eclipse. –

Odpowiedz

5

Wydaje mi się, że to błąd. Z JLS §5.5.2. Checked Casts and Unchecked Casts:

odlewu z typ S, typ ustawiony (§4.5) T jest zaznaczona , jeżeli co najmniej jeden z następujących warunków posiada:

  • S < T

  • wszystkie argumenty typu (§4.5.1) z T są nieograniczone symbole wieloznaczne

  • T <: s a ND nie ma podtyp X inne niż T, w której argumenty Rodzaj X, nie są zawarte w argumenty typu T.

podana przez rodzaje Base<T> i Derived<T, ?> jak S i T odpowiednio dwa pierwsze warunki wyraźnie się nie utrzymują.

Pozostaje trzeci warunek - który nie wytrzyma, czy możemy zidentyfikować podtyp Base<T> innego niż Derived<T, ?> którego argumenty typu nie są zawarte w argumentach typu produktu Derived<T, ?>. Jeśli ostrzeżenie jest poprawne, taki podtyp musi istnieć, ale nie mogę go zidentyfikować. Na przykład Derived<?, ?> nie działa, ponieważ nie jest podtypem Base<T>.

+0

Byłem niezdecydowany, aby opublikować tę odpowiedź, ponieważ kompilator Eclipse ma dobre wyniki z generycznymi materiałami, a zobaczenie tego ostrzeżenia w Eclipse sprawia, że ​​myślę, że czegoś mi brakuje. Jeśli źle odczytuję JLS, proszę skomentuj lub edytuj moją odpowiedź na poprawność. –

+1

JDK 7 nie wydaje ostrzeżenia. JLS 5/6 nie zlecił ostrzeżenia. Myślę, że twórcy kompilatorów jdt po prostu przegapili zmianę lub zignorowali ją z powodu błędu (powinno być: "... brak Podtypu X innego niż T, gdzie ** | T | = | X | i ** ..." –

+0

@ BenSchulz Tak, sam się zastanawiałem nad tym sformułowaniem - czy jest tam zgłoszony problem z JLS? –