Yanıtlar:
Java'daki jenerikler tamamen derleme zamanı bir yapıdır - derleyici tüm genel kullanımları doğru türe çevirir. Bu, önceki JVM çalışma zamanlarıyla geriye dönük uyumluluğu korumak içindir.
Bu:
List<ClassA> list = new ArrayList<ClassA>();
list.add(new ClassA());
ClassA a = list.get(0);
dönüşür (kabaca):
List list = new ArrayList();
list.add(new ClassA());
ClassA a = (ClassA)list.get(0);
Yani, jenerik olarak kullanılan herhangi bir şey Nesneye dönüştürülebilir olmalıdır (bu örnekte get(0)
an döndürür Object
) ve ilkel türler değildir. Yani jenerikte kullanılamazlar.
Dil tasarlanmıştır sonra yıllarca diline bir numara eklendiğinden Java'da, jenerik ... en azından kısmen ... yaptıkları yol çalışması 1 . Dil tasarımcıları , mevcut dil ve Java sınıf kitaplığı ile geriye dönük uyumlu bir tasarım bulmak zorunda kaldıklarında, jenerikler için kendi seçeneklerinde kısıtlandılar .
Diğer programlama dilleri (örn. C ++, C #, Ada), ilkel türlerin jenerikler için parametre türleri olarak kullanılmasına izin verir. Ancak bunu yapmanın ters tarafı, bu tür dillerin jenerik (veya şablon türleri) uygulamalarının tipik olarak her bir tür parametrelemesi için genel türün farklı bir kopyasının oluşturulmasını gerektirmesidir.
1 - Jeneriklerin Java 1.0'a dahil edilmemesinin nedeni zaman baskısıdır. Web tarayıcılarının sunduğu yeni pazar fırsatını doldurmak için Java dilini hızlı bir şekilde yayınlamaları gerektiğini hissettiler. James Gosling, zamanı olsaydı jenerik ilaçları dahil etmek isteyeceğini söyledi. Bu olsaydı Java dilinin nasıl göründüğü herkesin tahminidir.
Java jenerikleri geriye dönük uyumluluk için "Tip silme" kullanılarak uygulanır. Tüm genel türler çalışma zamanında Nesneye dönüştürülür. Örneğin,
public class Container<T> {
private T data;
public T getData() {
return data;
}
}
çalışma zamanında,
public class Container {
private Object data;
public Object getData() {
return data;
}
}
derleyici tip güvenliği sağlamak için uygun döküm sağlamakla yükümlüdür.
Container<Integer> val = new Container<Integer>();
Integer data = val.getData()
Olacak
Container val = new Container();
Integer data = (Integer) val.getData()
Şimdi soru neden "Nesne" çalışma zamanında tip olarak seçildi?
Cevap Nesnenin tüm nesnelerin üst sınıfıdır ve kullanıcı tanımlı herhangi bir nesneyi temsil edebilir.
Tüm temel öğeler " Nesne " den miras almadığından, onu genel bir tür olarak kullanamayız.
FYI: Valhalla Projesi yukarıdaki sorunu ele almaya çalışıyor.
Koleksiyonlar, türetilen bir tür gerektirecek şekilde tanımlanır java.lang.Object
. Temel türler bunu yapmaz.
Gereğince Java Belgeleri , genel tür değişkenler tek referans türleri değil, ilkel türleri ile örneği olabilir.
Bunun Java 10 Projesi'nde Valhalla Projesi kapsamında gelmesi bekleniyor .
Gelen Brian Goetz kağıt Uzmanlık Devlet
Bir yoktur mükemmel açıklama jenerik ilkel desteklenmez edildiği nedeni hakkında. Ve Java'nın gelecekteki sürümlerinde nasıl uygulanacağı .
Java'nın tüm referans örneklemeleri için bir sınıf üreten ve ilkel örneklemeler için destek içermeyen mevcut silinmiş uygulaması. (Bu homojen bir çeviridir ve Java'nın jeneriklerinin yalnızca referans türlerine göre değişebileceği kısıtlaması, JVM'nin bayt kodu kümesine göre homojen çevirinin sınırlamalarından kaynaklanır; bu, referans türlerine karşı ilkel türlere yönelik işlemler için farklı bayt kodları kullanır.) Bununla birlikte, Java'daki silinmiş jenerikler hem davranışsal parametriklik (jenerik yöntemler) hem de veri parametrikliği (jenerik tiplerin ham ve joker karakter örneklemeleri) sağlar.
...
homojen bir çeviri stratejisi seçilmiştir; burada genel tip değişkenleri bayt koduna dahil edilirken sınırlarına silinir. Bu, bir sınıf genel olsun ya da olmasın, yine de aynı ada sahip ve üye imzaları aynı olan tek bir sınıfa derlendiği anlamına gelir. Tür güvenliği derleme zamanında doğrulanır ve çalışma zamanı genel tür sistemi tarafından kaldırılmaz. Buna karşılık, bu, jeneriklerin sadece referans türleri üzerinde çalışabileceği kısıtlamasını getirdi, çünkü Object mevcut en genel türdür ve ilkel türlere uzanmaz.
Bir nesne oluştururken, type parametresi için ilkel bir türün yerini alamazsınız. Bu kısıtlamanın nedenine gelince, bu bir derleyici uygulama sorunudur. İlkel türlerin sanal makine yığınına yükleme ve depolama için kendi bayt kodu talimatları vardır. Bu nedenle, ilkel jenerikleri bu ayrı bayt kod yollarına derlemek imkansız değildir, ancak derleyiciyi karmaşık hale getirecektir.