Apa yang Anda coba lakukan sangat berguna dan saya menemukan bahwa saya perlu melakukannya sangat sering dalam kode yang saya tulis. Contoh use case:
Katakanlah kami memiliki antarmuka Foo
dan kami memiliki zorking
paket yang memiliki ZorkingFooManager
yang membuat dan mengelola instance dari paket-pribadi ZorkingFoo implements Foo
. (Skenario yang sangat umum.)
Jadi, ZorkingFooManager
perlu mengandung private Collection<ZorkingFoo> zorkingFoos
tetapi perlu mengekspos a public Collection<Foo> getAllFoos()
.
Sebagian besar programmer java tidak akan berpikir dua kali sebelum mengimplementasikan getAllFoos()
sebagai mengalokasikan yang baru ArrayList<Foo>
, mengisinya dengan semua elemen dari zorkingFoos
dan mengembalikannya. Saya menikmati menghibur pikiran bahwa sekitar 30% dari semua siklus jam yang dikonsumsi oleh kode java yang berjalan pada jutaan mesin di seluruh planet ini tidak melakukan apa pun selain membuat salinan ArrayLists yang tidak berguna yang merupakan mikrodetik sampah yang dikumpulkan setelah pembuatannya.
Solusi untuk masalah ini, tentu saja, menurunkan koleksi. Inilah cara terbaik untuk melakukannya:
static <T,U extends T> List<T> downCastList( List<U> list )
{
return castList( list );
}
Yang membawa kita ke castList()
fungsi:
static <T,E> List<T> castList( List<E> list )
{
@SuppressWarnings( "unchecked" )
List<T> result = (List<T>)list;
return result;
}
result
Variabel perantara diperlukan karena penyimpangan bahasa java:
return (List<T>)list;
menghasilkan pengecualian "pemain yang tidak dicentang"; sejauh ini baik; tapi kemudian:
@SuppressWarnings( "unchecked" ) return (List<T>)list;
adalah penggunaan anotasi penindasan-peringatan secara ilegal.
Jadi, meskipun tidak halal untuk digunakan @SuppressWarnings
pada return
pernyataan, tampaknya baik-baik saja untuk menggunakannya pada tugas, sehingga variabel "hasil" tambahan menyelesaikan masalah ini. (Itu harus dioptimalkan baik oleh kompiler atau oleh JIT.)