Tip güvenliğini korurken tam olarak aradığınız türde bir dizi elde etmek için jenerikleri nasıl kullanacağınız (diğer cevapların aksine, size bir Object
dizi geri verir veya derleme zamanında uyarılara neden olur):
import java.lang.reflect.Array;
public class GenSet<E> {
private E[] a;
public GenSet(Class<E[]> clazz, int length) {
a = clazz.cast(Array.newInstance(clazz.getComponentType(), length));
}
public static void main(String[] args) {
GenSet<String> foo = new GenSet<String>(String[].class, 1);
String[] bar = foo.a;
foo.a[0] = "xyzzy";
String baz = foo.a[0];
}
}
Bu, uyarılar olmadan derler ve gördüğünüz gibi main
, bir örnek GenSet
olarak bildirdiğiniz herhangi bir tür için a
, bu tür bir diziye atayabilir ve bu türdeki a
bir değişkene öğeyi atayabilirsiniz , yani dizi ve dizideki değerler doğru tiptedir.
Java Öğreticileri'nde tartışıldığı gibi, sınıf değişmezlerini çalışma zamanı belirteci olarak kullanarak çalışır . Sınıf değişmezleri derleyici tarafından örnek olarak ele alınır java.lang.Class
. Birini kullanmak için ile birlikte bir sınıfın adını takip edin .class
. Yani, sınıfı temsil eden String.class
bir Class
nesne gibi davranır String
. Bu aynı zamanda arayüzler, numaralandırmalar, herhangi bir boyutlu diziler (örn. String[].class
), İlkel öğeler (ör. int.class
) Ve anahtar kelime void
(ör. void.class
) İçin de geçerlidir.
Class
kendisi (ilan geneldir Class<T>
, burada T
bu tür için standları Class
nesne temsil etmektedir) türü, yani String.class
bir Class<String>
.
Bu nedenle, yapıcıyı her çağırdığınızda, örneğin bildirilen türünün (örn. İçin ) GenSet
bir dizisini temsil eden ilk bağımsız değişken için bir sınıf değişmezi iletirsiniz . İlkel değerler tür değişkenleri için kullanılamayacağından, bir dizi temel öğe elde edemeyeceğinizi unutmayın.GenSet
String[].class
GenSet<String>
Yapıcı içinde, yöntemin çağrılması, cast
iletilen iletilen Object
argümanı Class
yöntemin çağrıldığı nesnenin temsil ettiği sınıfa döndürür . Statik yöntemi çağırma newInstance
içinde java.lang.reflect.Array
bir şekilde geri dönüş Object
ile temsil edilen tipte bir dizi Class
ilk bağımsız değişken olarak ve belirtilen uzunlukta geçirilen nesne int
ikinci bağımsız değişken olarak geçti. Yöntem, arama getComponentType
bir döner Class
dizi bileşen tipi ifade eden nesne ile temsil edilen Class
(örneğin, yöntem çağrıldığı nesne String.class
için String[].class
, null
eğer Class
nesne bir dizi temsil etmez).
Bu son cümle tam olarak doğru değil. Çağırma sınıfı temsil eden String[].class.getComponentType()
bir Class
nesne döndürür String
, ancak türü Class<?>
değil Class<String>
, bu nedenle aşağıdaki gibi bir şey yapamazsınız.
String foo = String[].class.getComponentType().cast("bar"); // won't compile
Aynı şey, Class
bir Class
nesneyi döndüren her yöntem için de geçerlidir .
Joachim Sauer'ın bu cevaba ilişkin yorumu ile ilgili olarak (kendim hakkında yorum yapmak için yeterli üne sahip değilim), cast'ı kullanan örnek T[]
bir uyarı ile sonuçlanacaktır, çünkü derleyici bu durumda tip güvenliği garanti edemez.
Ingo'nun yorumlarıyla ilgili düzenleme:
public static <T> T[] newArray(Class<T[]> type, int size) {
return type.cast(Array.newInstance(type.getComponentType(), size));
}