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 Objectdizi 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 GenSetolarak bildirdiğiniz herhangi bir tür için a, bu tür bir diziye atayabilir ve bu türdeki abir 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.classbir Classnesne 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.
Classkendisi (ilan geneldir Class<T>, burada Tbu tür için standları Classnesne temsil etmektedir) türü, yani String.classbir Class<String>.
Bu nedenle, yapıcıyı her çağırdığınızda, örneğin bildirilen türünün (örn. İçin ) GenSetbir 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.GenSetString[].classGenSet<String>
Yapıcı içinde, yöntemin çağrılması, castiletilen iletilen Objectargümanı Classyöntemin çağrıldığı nesnenin temsil ettiği sınıfa döndürür . Statik yöntemi çağırma newInstanceiçinde java.lang.reflect.Arraybir şekilde geri dönüş Objectile temsil edilen tipte bir dizi Classilk bağımsız değişken olarak ve belirtilen uzunlukta geçirilen nesne intikinci bağımsız değişken olarak geçti. Yöntem, arama getComponentTypebir döner Classdizi bileşen tipi ifade eden nesne ile temsil edilen Class(örneğin, yöntem çağrıldığı nesne String.classiçin String[].class, nulleğer Classnesne 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 Classnesne 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, Classbir Classnesneyi 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));
}