1. 程式人生 > >java中泛型建立陣列的總結

java中泛型建立陣列的總結

在java中,不能通過直接通過T[] tarr=new T[10]的方式來建立陣列,最簡單的方式便是通過Array.newInstance(Class<t>type,int size)的方式來建立陣列例如下面的程式

[java] view plaincopyprint?
  1. publicclass ArrayMaker<T> {  
  2.     private Class<T> type;  
  3.     public ArrayMaker(Class<T> type) {  
  4.         this.type = type;  
  5.     }  
  6.     @SuppressWarnings
    ("unchecked")  
  7.     T[] createArray(int size) {  
  8.         return (T[]) Array.newInstance(type, size);  
  9.     }  
  10.     List<T> createList() {  
  11.         returnnew ArrayList<T>();  
  12.     }  
  13.     /** 
  14.      * @param args 
  15.      */
  16.     publicstaticvoid main(String[] args) {  
  17.         /* 
  18.          * Even though kind is stored as Class<T> , erasure means that it is actually just being stored as a Class, with
     
  19.          * no parameter. So, when you do some thing with it, as in creating an array, Array.newInstance( ) doesn’t 
  20.          * actually have the type information that’s implied in kind; so it cannot produce the specific result, wh ich 
  21.          * must therefore be cast, which produces a warning that you cannot satisfy.
     
  22.          */
  23.         ArrayMaker<Type> am2 = new ArrayMaker<Type>(Type.class);  
  24.         System.out.println(Arrays.asList(am2.createArray(10)));  
  25.         System.out.println(Arrays.asList(am2.createList()));  
  26.     }  
  27. }  
  28. class Type {  
  29.     @Override
  30.     public String toString() {  
  31.         return"type";  
  32.     }  
  33. }  

上面的這個例子比較簡單,但是如果你有接觸過泛型陣列,你便對他的複雜度有一定的瞭解,由於建立泛型陣列比較複雜,所以在實際的應用過程中一般會選擇List的對泛型進行儲存,如果實在需要使用泛型陣列,則需要注意陣列的在執行時的型別,think in java這本書中,對泛型陣列的處理通過四個小程式對其進行了比較完整的描述

程式一:這個程式主要說明了,在使用泛型陣列中容易出現的問題,由於書中對於程式的說明比較詳細,所以只對程式做引用

[java] view plaincopyprint?
  1. class Generic<T> {  
  2. }  
  3. publicclass ArrayofGeneric {  
  4.     publicstaticvoid main(String[] args) {  
  5.         Generic<Integer>[] genArr;  
  6.         /* 
  7.          * will throw ClassCastException :The problem is that arrays keep track of their actual type, and that type is 
  8.          * established at the point of creation of the array. So even though genArr has been cast to a Generic < Integer 
  9.          * >[] , that information only exists at compile time (and without the @SuppressWarnings annotation, you’d get a 
  10.          * warning for that cast). At run time, it’s still an array of Object, and that causes problems. 
  11.          */
  12.         // genArr = (Generic<Integer>[]) new Object[] {};
  13.         /* can not create a generic of array */
  14.         // genArr=new Generic<Integer>[2];
  15.         genArr = (Generic<Integer>[]) new Generic[2];  
  16.         System.out.println(genArr);  
  17.     }  
  18. }  

程式二:這個程式主要是說明在程式的執行過程中,泛型陣列的型別資訊會被擦除,且在執行的過程中陣列的型別有且僅有Object[],如果我們強制轉換成T[]型別的話,雖然在編譯的時候不會有異常產生,但是執行時會有ClassCastException丟擲 [java] view plaincopyprint?
  1. /** 
  2.  *  
  3.  * Because of erasure, the runtime type of the array can only be Object[]. If we immediately cast it to T[], then at 
  4.  * compile time the actual type of the array is lost, and the compiler may miss out on some potential error checks. 
  5.  *  
  6.  *  
  7.  *  
  8.  * archive $ProjectName: $ 
  9.  *  
  10.  * @author Admin 
  11.  *  
  12.  * @version $Revision: $ $Name: $ 
  13.  */
  14. publicclass ArrayOfGeneric2<T> {  
  15.     public T[] ts;  
  16.     public ArrayOfGeneric2(int size) {  
  17.         ts = (T[]) new Object[size];  
  18.     }  
  19.     public T get(int index) {  
  20.         return ts[index];  
  21.     }  
  22.     public T[] rep() {  
  23.         return ts;  
  24.     }  
  25.     publicvoid set(int index, T t) {  
  26.         ts[index] = t;  
  27.     }  
  28.     publicstaticvoid main(String[] args) {  
  29.         ArrayOfGeneric2<String> aog2 = new ArrayOfGeneric2<String>(10);  
  30.         Object[] objs = aog2.rep();  
  31.         System.out.println(objs);  
  32.         /* will throw ClassCastException */
  33.        // String[] strs = aog2.rep();
  34.         // System.out.println(strs);
  35.     }  
  36. }  

程式三:主要說明在物件中通過用Object[]來儲存資料,則生成物件是,可以對其持有的物件在T和object之間進行轉換,但是當設計到陣列的轉換時,還是會報ClassCastException [java] view plaincopyprint?
  1. /** 
  2.  *  
  3.  * Initially, this doesn’t look very different compare with ArrayOfGeneric2.java , just that the cast has been moved. 
  4.  * Without the ©SuppressWarnings annotations, you will still get "unchecked" warnings. However, the internal 
  5.  * representation is now Object[] rather than T[]. When get( ) is called, it casts the object to T, which is in fact the 
  6.  * correct type, so that is safe. However, if you call rep( ) , it again attempts to cast the Object[] to a T[], which 
  7.  * is still incorrect, and produces a warning at compile time and an exception at run time. Thus there’s no way to 
  8.  * subvert the type of the underlying array, which can only be Object[]. The advantage of treating array internally as 
  9.  * Object[] instead of T[] is that it’s less likely that you’ll forget the runtime type of the array and accidentally 
  10.  * introduce a bug (although the majority, and perhaps all, of such bugs would be rapidly detected at run time) 
  11.  *  
  12.  *  
  13.  *  
  14.  * archive $ProjectName: $ 
  15.  *  
  16.  * @author Admin 
  17.  *  
  18.  * @version $Revision: $ $Name: $ 
  19.  */
  20. publicclass ArrayOfGeneric3<T> {  
  21.     Object[] ts;  
  22.     public ArrayOfGeneric3(int size) {  
  23.         ts = new Object[size];  
  24.     }  
  25.     public T get(int index) {  
  26.         return (T) ts[index];  
  27.     }  
  28.     public T[] rep() {  
  29.         return (T[]) ts;  
  30.     }  
  31.     publicvoid set(int index, T t) {  
  32.         ts[index] = t;  
  33.     }  
  34.     publicstaticvoid main(String[] args) {  
  35.         ArrayOfGeneric3<Integer> aog2 = new ArrayOfGeneric3<Integer>(10);  
  36.         Object[] objs = aog2.rep();  
  37.         for (int i = 0; i < 10; i++) {  
  38.             aog2.set(i, i);  
  39.             System.out.println(aog2.get(i));  
  40.         }  
  41.             Integer[] strs = aog2.rep();  
  42.             System.out.println(strs);  
  43.     }  
  44. }  

程式四:是對泛型陣列相對而言比較完美的解決方案 [java] view plaincopyprint?
  1. /** 
  2.  *  
  3.  * The type token Class<T> is passed into the constructor in order to recover from the erasure, so that we can create 
  4.  * the actual type of array that we need, although the warning from the cast must be suppressed with @SuppressWarnings. 
  5.  * Once we do get the actual type, we can return it and get the desired results, as you see in main( ). The runtime type 
  6.  * of the array is the exact type T[]. 
  7.  *  
  8.  * @author Admin 
  9.  *  
  10.  * @version $Revision: $ $Name: $ 
  11.  */
  12. publicclass ArrayOfGeneric4<T> {  
  13.     T[] ts;  
  14.     public ArrayOfGeneric4(Class<T> type, int size) {  
  15.         /* to solution array of generic key code! */
  16.         ts = (T[]) Array.newInstance(type, size);  
  17.     }  
  18.     public T get(int index) {  
  19.         return ts[index];  
  20.     }  
  21.     public T[] rep() {  
  22.         return ts;  
  23.     }  
  24.     publicvoid set(int index, T t) {  
  25.         ts[index] = t;  
  26.     }  
  27.     publicstaticvoid main(String[] args) {  
  28.         ArrayOfGeneric4<Integer> aog2 = new ArrayOfGeneric4<Integer>(Integer.class10);  
  29.         Object[] objs = aog2.rep();  
  30.         for (int i = 0; i < 10; i++) {  
  31.             aog2.set(i, i);  
  32.             System.out.println(aog2.get(i));  
  33.         }  
  34.         try {  
  35.             Integer[] strs = aog2.rep();  
  36.             System.out.println("user Array.newInstance to create generci of array was successful!!!!! ");  
  37.         } catch (Exception ex) {  
  38.             ex.printStackTrace();  
  39.         }  
  40.     }  
  41. }  

泛型這一章節的內容從擦除開始,覺得都是非常的難懂,如果哪位同志有比較好的建議,希望能不惜指教!