Java中泛型創(chuàng)建數(shù)組的總結(jié)
在java中,不能通過直接通過T[] tarr=new T[10]的方式來創(chuàng)建數(shù)組,最簡單的方式便是通過Array.newInstance(Class<t>type,int size)的方式來創(chuàng)建數(shù)組例如下面的程序。
- public class ArrayMaker<T> {
 - private Class<T> type;
 - public ArrayMaker(Class<T> type) {
 - this.type = type;
 - }
 - @SuppressWarnings("unchecked")
 - T[] createArray(int size) {
 - return (T[]) Array.newInstance(type, size);
 - }
 - List<T> createList() {
 - return new ArrayList<T>();
 - }
 - /**
 - * @param args
 - */
 - public static void main(String[] args) {
 - /*
 - * Even though kind is stored as Class<T> , erasure means that it is actually just being stored as a Class, with
 - * no parameter. So, when you do some thing with it, as in creating an array, Array.newInstance( ) doesn’t
 - * actually have the type information that’s implied in kind; so it cannot produce the specific result, wh ich
 - * must therefore be cast, which produces a warning that you cannot satisfy.
 - */
 - ArrayMaker<Type> am2 = new ArrayMaker<Type>(Type.class);
 - System.out.println(Arrays.asList(am2.createArray(10)));
 - System.out.println(Arrays.asList(am2.createList()));
 - }
 - }
 - class Type {
 - @Override
 - public String toString() {
 - return "type";
 - }
 - }
 
上面的這個例子比較簡單,但是如果你有接觸過泛型數(shù)組,你便對他的復(fù)雜度有一定的了解,由于創(chuàng)建泛型數(shù)組比較復(fù)雜,所以在實(shí)際的應(yīng)用過程中一般會選擇List的對泛型進(jìn)行存儲,如果實(shí)在需要使用泛型數(shù)組,則需要注意數(shù)組的在運(yùn)行時的類型,think in java這本書中,對泛型數(shù)組的處理通過四個小程序?qū)ζ溥M(jìn)行了比較完整的描述。
程序一:這個程序主要說明了,在使用泛型數(shù)組中容易出現(xiàn)的問題,由于書中對于程序的說明比較詳細(xì),所以只對程序做引用。
- class Generic<T> {
 - }
 - public class ArrayofGeneric {
 - public static void main(String[] args) {
 - Generic<Integer>[] genArr;
 - /*
 - * will throw ClassCastException :The problem is that arrays keep track of their actual type, and that type is
 - * established at the point of creation of the array. So even though genArr has been cast to a Generic < Integer
 - * >[] , that information only exists at compile time (and without the @SuppressWarnings annotation, you’d get a
 - * warning for that cast). At run time, it’s still an array of Object, and that causes problems.
 - */
 - // genArr = (Generic<Integer>[]) new Object[] {};
 - /* can not create a generic of array */
 - // genArr=new Generic<Integer>[2];
 - genArr = (Generic<Integer>[]) new Generic[2];
 - System.out.println(genArr);
 - }
 - }
 
程序二:這個程序主要是說明在程序的執(zhí)行過程中,泛型數(shù)組的類型信息會被擦除,且在運(yùn)行的過程中數(shù)組的類型有且僅有Object[],如果我們強(qiáng)制轉(zhuǎn)換成T[]類型的話,雖然在編譯的時候不會有異常產(chǎn)生,但是運(yùn)行時會有ClassCastException拋出。
- /**
 - *
 - * Because of erasure, the runtime type of the array can only be Object[]. If we immediately cast it to T[], then at
 - * compile time the actual type of the array is lost, and the compiler may miss out on some potential error checks.
 - *
 - *
 - *
 - * archive $ProjectName: $
 - *
 - * @author Admin
 - *
 - * @version $Revision: $ $Name: $
 - */
 - public class ArrayOfGeneric2<T> {
 - public T[] ts;
 - public ArrayOfGeneric2(int size) {
 - ts = (T[]) new Object[size];
 - }
 - public T get(int index) {
 - return ts[index];
 - }
 - public T[] rep() {
 - return ts;
 - }
 - public void set(int index, T t) {
 - ts[index] = t;
 - }
 - public static void main(String[] args) {
 - ArrayOfGeneric2<String> aog2 = new ArrayOfGeneric2<String>(10);
 - Object[] objs = aog2.rep();
 - System.out.println(objs);
 - /* will throw ClassCastException */
 - // String[] strs = aog2.rep();
 - // System.out.println(strs);
 - }
 - }
 
程序三:主要說明在對象中通過用Object[]來保存數(shù)據(jù),則生成對象是,可以對其持有的對象在T和object之間進(jìn)行轉(zhuǎn)換,但是當(dāng)設(shè)計(jì)到數(shù)組的轉(zhuǎn)換時,還是會報ClassCastException
- /**
 - *
 - * Initially, this doesn’t look very different compare with ArrayOfGeneric2.java , just that the cast has been moved.
 - * Without the ©SuppressWarnings annotations, you will still get "unchecked" warnings. However, the internal
 - * representation is now Object[] rather than T[]. When get( ) is called, it casts the object to T, which is in fact the
 - * correct type, so that is safe. However, if you call rep( ) , it again attempts to cast the Object[] to a T[], which
 - * is still incorrect, and produces a warning at compile time and an exception at run time. Thus there’s no way to
 - * subvert the type of the underlying array, which can only be Object[]. The advantage of treating array internally as
 - * Object[] instead of T[] is that it’s less likely that you’ll forget the runtime type of the array and accidentally
 - * introduce a bug (although the majority, and perhaps all, of such bugs would be rapidly detected at run time)
 - *
 - *
 - *
 - * archive $ProjectName: $
 - *
 - * @author Admin
 - *
 - * @version $Revision: $ $Name: $
 - */
 - public class ArrayOfGeneric3<T> {
 - Object[] ts;
 - public ArrayOfGeneric3(int size) {
 - ts = new Object[size];
 - }
 - public T get(int index) {
 - return (T) ts[index];
 - }
 - public T[] rep() {
 - return (T[]) ts;
 - }
 - public void set(int index, T t) {
 - ts[index] = t;
 - }
 - public static void main(String[] args) {
 - ArrayOfGeneric3<Integer> aog2 = new ArrayOfGeneric3<Integer>(10);
 - Object[] objs = aog2.rep();
 - for (int i = 0; i < 10; i++) {
 - aog2.set(i, i);
 - System.out.println(aog2.get(i));
 - }
 - Integer[] strs = aog2.rep();
 - System.out.println(strs);
 - }
 - }
 
程序四:是對泛型數(shù)組相對而言比較***的解決方案
- /**
 - *
 - * The type token Class<T> is passed into the constructor in order to recover from the erasure, so that we can create
 - * the actual type of array that we need, although the warning from the cast must be suppressed with @SuppressWarnings.
 - * Once we do get the actual type, we can return it and get the desired results, as you see in main( ). The runtime type
 - * of the array is the exact type T[].
 - *
 - * @author Admin
 - *
 - * @version $Revision: $ $Name: $
 - */
 - public class ArrayOfGeneric4<T> {
 - T[] ts;
 - public ArrayOfGeneric4(Class<T> type, int size) {
 - /* to solution array of generic key code! */
 - ts = (T[]) Array.newInstance(type, size);
 - }
 - public T get(int index) {
 - return ts[index];
 - }
 - public T[] rep() {
 - return ts;
 - }
 - public void set(int index, T t) {
 - ts[index] = t;
 - }
 - public static void main(String[] args) {
 - ArrayOfGeneric4<Integer> aog2 = new ArrayOfGeneric4<Integer>(Integer.class, 10);
 - Object[] objs = aog2.rep();
 - for (int i = 0; i < 10; i++) {
 - aog2.set(i, i);
 - System.out.println(aog2.get(i));
 - }
 - try {
 - Integer[] strs = aog2.rep();
 - System.out.println("user Array.newInstance to create generci of array was successful!!!!! ");
 - } catch (Exception ex) {
 - ex.printStackTrace();
 - }
 - }
 - }
 
泛型這一章節(jié)的內(nèi)容從擦除開始,覺得都是非常的難懂,如果哪位同志有比較好的建議,希望能不惜指教!
原文鏈接:http://blog.csdn.net/sun7545526/article/details/7262486
【編輯推薦】















 
 
 





 
 
 
 