Yapmaya çalıştığınız şey çok yararlı ve bunu yazdığım kodda çok sık yapmam gerektiğini görüyorum. Örnek bir kullanım durumu:
Bir arayüzümüz olduğunu Foo
ve paket-özel örneklerini yaratan ve yöneten bir zorking
paketimiz olduğunu ZorkingFooManager
varsayalım ZorkingFoo implements Foo
. (Çok yaygın bir senaryo.)
Yani, ZorkingFooManager
a içermesi gerekiyor private Collection<ZorkingFoo> zorkingFoos
ama a public Collection<Foo> getAllFoos()
.
Çoğu java programcısı, getAllFoos()
yeni bir tane ayırmayı ArrayList<Foo>
, onu tüm öğeleriyle zorkingFoos
doldurup geri döndürmeyi uygulamadan önce iki kez düşünmez . Gezegenin dört bir yanındaki milyonlarca makinede çalışan java kodunun tükettiği tüm saat döngülerinin yaklaşık% 30'unun, oluşturulduktan sonra mikrosaniyelerden sonra çöp olarak toplanan ArrayList'lerin böylesine gereksiz kopyalarını oluşturmaktan başka hiçbir şey yapmadığı düşüncesini eğlendirmekten keyif alıyorum.
Bu problemin çözümü elbette koleksiyonun aşağı dökümünü yapmaktır. İşte bunu yapmanın en iyi yolu:
static <T,U extends T> List<T> downCastList( List<U> list )
{
return castList( list );
}
Bu da bizi castList()
işleve getiriyor :
static <T,E> List<T> castList( List<E> list )
{
@SuppressWarnings( "unchecked" )
List<T> result = (List<T>)list;
return result;
}
result
Java dilinin bir sapkınlığı nedeniyle ara değişken gereklidir:
return (List<T>)list;
bir "kontrol edilmeyen çevrim" istisnası üretir; çok uzak çok iyi; ama sonra:
@SuppressWarnings( "unchecked" ) return (List<T>)list;
bastırma uyarıları ek açıklamasının yasa dışı kullanımıdır.
Dolayısıyla, @SuppressWarnings
bir return
ifadede kullanmak koşer olmasa da, görünüşe göre onu bir atamada kullanmak iyidir, bu nedenle ekstra "sonuç" değişkeni bu sorunu çözer. (Derleyici veya JIT tarafından yine de optimize edilmelidir.)