Quello che stai cercando di fare è molto utile e trovo che devo farlo molto spesso nel codice che scrivo. Un esempio di utilizzo:
Supponiamo che abbiamo un'interfaccia Fooe abbiamo un zorkingpacchetto che ha un pacchetto ZorkingFooManagerche crea e gestisce istanze di pacchetto-private ZorkingFoo implements Foo. (Uno scenario molto comune.)
Quindi, ZorkingFooManagerdeve contenere un private Collection<ZorkingFoo> zorkingFoosma deve esporre a public Collection<Foo> getAllFoos().
La maggior parte dei programmatori Java non ci penserebbe due volte prima di implementare getAllFoos()come allocare un nuovo ArrayList<Foo>, popolarlo con tutti gli elementi zorkingFoose restituirlo. Mi piace intrattenere l'idea che circa il 30% di tutti i cicli di clock consumati dal codice Java in esecuzione su milioni di macchine in tutto il pianeta non stiano facendo altro che creare copie così inutili di ArrayList che sono microsecondi raccolti dalla spazzatura dopo la loro creazione.
La soluzione a questo problema è, ovviamente, il down-casting della raccolta. Ecco il modo migliore per farlo:
static <T,U extends T> List<T> downCastList( List<U> list )
{
return castList( list );
}
Il che ci porta alla castList()funzione:
static <T,E> List<T> castList( List<E> list )
{
@SuppressWarnings( "unchecked" )
List<T> result = (List<T>)list;
return result;
}
La resultvariabile intermedia è necessaria a causa di una perversione del linguaggio java:
return (List<T>)list;produce un'eccezione "non selezionata"; Fin qui tutto bene; ma allora:
@SuppressWarnings( "unchecked" ) return (List<T>)list; è un uso illegale dell'annotazione degli avvisi di soppressione.
Quindi, anche se non è kosher da usare @SuppressWarningssu returnun'istruzione, è apparentemente bene usarlo su un compito, quindi la variabile "risultato" extra risolve questo problema. (Dovrebbe essere comunque ottimizzato dal compilatore o dalla JIT.)