Was Sie versuchen zu tun, ist sehr nützlich und ich finde, dass ich es sehr oft in Code tun muss, den ich schreibe. Ein Beispiel für einen Anwendungsfall:
Angenommen, wir haben eine Schnittstelle Foo
und ein zorking
Paket, das ZorkingFooManager
Instanzen von package-private erstellt und verwaltet ZorkingFoo implements Foo
. (Ein sehr häufiges Szenario.)
So ZorkingFooManager
muss ein enthalten , private Collection<ZorkingFoo> zorkingFoos
aber es braucht eine belichten public Collection<Foo> getAllFoos()
.
Die meisten Java-Programmierer würden nicht zweimal überlegen, bevor sie getAllFoos()
ein neues ArrayList<Foo>
zuweisen, es mit allen Elementen aus zorkingFoos
füllen und es zurückgeben. Ich genieße es, den Gedanken zu unterhalten, dass etwa 30% aller Taktzyklen, die von Java-Code auf Millionen von Computern auf der ganzen Welt verbraucht werden, nichts anderes tun, als solche nutzlosen Kopien von ArrayLists zu erstellen, die nach ihrer Erstellung Mikrosekunden mit Müll gesammelt werden.
Die Lösung für dieses Problem besteht natürlich darin, die Sammlung herunterzuwerfen. Hier ist der beste Weg, dies zu tun:
static <T,U extends T> List<T> downCastList( List<U> list )
{
return castList( list );
}
Was uns zur castList()
Funktion bringt :
static <T,E> List<T> castList( List<E> list )
{
@SuppressWarnings( "unchecked" )
List<T> result = (List<T>)list;
return result;
}
Die Zwischenvariable result
ist aufgrund einer Perversion der Java-Sprache erforderlich:
return (List<T>)list;
erzeugt eine "ungeprüfte Besetzung" -Ausnahme; So weit, ist es gut; aber dann:
@SuppressWarnings( "unchecked" ) return (List<T>)list;
ist eine illegale Verwendung der Annotation "Unterdrückungswarnungen".
Obwohl die Verwendung @SuppressWarnings
für eine return
Anweisung nicht koscher ist , ist es anscheinend in Ordnung, sie für eine Zuweisung zu verwenden. Die zusätzliche Variable "result" löst dieses Problem. (Es sollte sowieso entweder vom Compiler oder von der JIT optimiert werden.)