2013-07-26 11 views
5

Supponiamo che io sono questo:Casting per sottotipi generiche di una classe generica

class Base<T> {} 

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

Poi, nel mio codice, posso tranquillamente gettato senza un avvertimento come questo:

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

che va bene. Ma se la classe derivata ha più parametri di tipo, non funziona più:

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

Perché è così? C'è qualcosa di ovvio che mi manca qui?

+0

Perché non funziona? Ha funzionato per me ... – m3th0dman

+0

Quello che "non funziona" è che ottengo un avviso non controllato anche se questo cast è perfettamente sicuro. –

+0

Che compilatore? Lo sto vedendo con il compilatore Eclipse. –

risposta

5

Questo mi sembra un insetto. Da JLS §5.5.2. Checked Casts and Unchecked Casts:

Un cast da un tipo S di un tipo parametrico (§4.5) T è selezionata se almeno una delle seguenti condizioni vale:

  • S <: T

  • Tutti gli argomenti di tipo (§4.5.1) di T sono jolly illimitati

  • T <: S un nd S ha sottotipo X diverso da T dove gli argomenti di tipo X non sono contenute negli argomenti tipo di T.

Dato i tipi di Base<T> e Derived<T, ?> come S e T rispettivamente, i primi due le condizioni chiaramente non reggono.

che lascia la terza condizione - che non si terrà se siamo in grado di identificare un sottotipo di Base<T> diverso Derived<T, ?> cui argomenti di tipo non sono contenute nei argomenti di tipo di Derived<T, ?>. Se l'avviso è corretto, tale sottotipo deve esistere, ma non posso identificarlo. Ad esempio, Derived<?, ?> non funziona perché non è un sottotipo di Base<T>.

+0

Ero esitante a postare questa risposta perché il compilatore Eclipse ha un buon track record con i generici e vedere questo avviso in Eclipse mi fa pensare che mi manchi qualcosa. Se sto fraintendendo il JLS, per favore commenta o modifica la mia risposta per correttezza. –

+1

JDK 7 non emette l'avviso. JLS 5/6 non ha richiesto l'avvertimento. Penso che gli sviluppatori di compilatori jdt abbiano semplicemente perso la modifica o lo ignorassero a causa dell'errore (dovrebbe essere: "... nessun sottotipo X diverso da T dove ** | T | = | X | e ** ..." –

+0

@ BenSchulz Sì, mi stavo chiedendo a proposito di questa dicitura - c'è un problema JLS segnalato per questo? –

Problemi correlati