2014-02-18 73 views
3

考慮Java的ArrayList#toArray方法的以下測試。請注意,我借用了這個有幫助的answer中的代碼。在編譯時捕獲ArrayStoreException

public class GenericTest { 
    public static void main(String [] args) { 
     ArrayList<Integer> foo = new ArrayList<Integer>(); 
     foo.add(1); 
     foo.add(2); 
     foo.add(3); 
     foo.add(4); 
     foo.add(5); 
     Integer[] bar = foo.toArray(new Integer[10]); 
     System.out.println("bar.length: " + bar.length); 

     for(Integer b : bar) { System.out.println(b); } 

     String[] baz = foo.toArray(new String[10]);  // ArrayStoreException 
     System.out.println("baz.length: " + baz.length); 
    } 
} 

但是,請注意,會有一個ArrayStoreException試圖把一個IntegerString[]時。

輸出:

$>javac GenericTest.java && java -cp . GenericTest 
bar.length: 10 
1 
2 
3 
4 
5 
null 
null 
null 
null 
null 
Exception in thread "main" java.lang.ArrayStoreException 
     at java.lang.System.arraycopy(Native Method) 
     at java.util.ArrayList.toArray(Unknown Source) 
     at GenericTest.main(GenericTest.java:16) 

可通過Java泛型防止在編譯時這個錯誤?

回答

2

List#toArray(T[])聲明一個通用的方法如

<T> T[] toArray(T[] a); 

所以類型參數是從給定的數組的類型或者推斷出的或與<Type>符號前綴方法調用。

所以,你可以做

String[] baz = foo.<Integer>toArray(new String[10]); // doesn't compile 

但我認爲這是你能做到的最好。

但是在這個意義上,您可以清楚地看到IntegerString(或反之亦然)不匹配。

注意,這是一個文件化例外

ArrayStoreException信息 - 如果指定數組的運行時類型是 不運行時類型的每一個元素的的超類型在此列表

所以我認爲你不應該在編譯時試圖找到它。

0

方法Collection.toArray不能出於兼容性原因而改變。

public static <T> T[] toArray(List<? extends T> list, T[] t) { 
    return list.toArray(t); 
} 

這種方法將拒絕該例子匹配String[] s=toArray(new ArrayList<Integer>(), new String[0]);

不過,對於自己的代碼,如果您使用因此你的方法,你可以創建一個(更多)類型安全助手可以保護你從ArrayStoreException方法數組子類型規則的情況下,你的問題的,但要注意:它不會拒絕,因爲預泛型「String[]

Object[] s=toArray(new ArrayList<Integer>(), new String[0]); 

是一個子類0「規則。這不能用現有的Java語言來解決。

+2

downvote的任何解釋? – Holger

0

ArrayStoreException是運行時異常而不是編譯時間並在運行時拋出,it表示不同類型的對象正在存儲在數組中。對象x [] = new String [3]; x [0] =新的整數(0); 你可以在編譯時發現它的唯一方法是通過使用< 整數>鍵入如下

foo.<Integer>toArray(new String[10]); 

以上將引發編譯時錯誤作爲 The parameterized method <Integer>toArray(Integer[]) of type List<Integer> is not applicable for the arguments (String[])