2013-02-23 44 views
2

爲什麼Collection<E>.toArray()(非參數化方法)返回Object[]爲什麼Collection <E> #toArray()不返回E []?

這是有意識的決定之一嗎?如果想要的話,toArray()方法不能返回E[]是否有任何理由?

+0

類型擦除是原因。 java不知道T在運行時是什麼 - 因此它不能創建適當類型的數組。另一種toArray的「typesafe」變體需要一個「原型」數組,它具有可以複製的正確類型(在編譯時固定!)。 – Pyranja 2013-02-23 07:24:49

+0

這是歷史。該方法早於泛型,並保持其現有形式以避免打破傳統代碼。 – Perception 2013-02-23 07:25:21

+0

我不太確定。我沒有辦法在該方法中獲得'E'類。 – 2013-02-23 07:28:29

回答

6

這是因爲在不知道類型Class<T>的情況下不能實例化T類型的數組。將其與toArray(T[] array)進行對比,其具有以下來源(來自LinkedList的示例)。請注意,傳入的數組不僅用作可能的容器,而且還可能實例化一個新類型的數組。如果T不是E的超類,則此代碼將引發異常;如果對象不能添加到數組中。

@SuppressWarnings("unchecked") 
public <T> T[] toArray(T[] a) { 
    if (a.length < size) 
     a = (T[])java.lang.reflect.Array.newInstance(
          a.getClass().getComponentType(), size); 
    int i = 0; 
    Object[] result = a; 
    for (Node<E> x = first; x != null; x = x.next) 
     result[i++] = x.item; 

    if (a.length > size) 
     a[size] = null; 

    return a; 
} 
1

Java中的泛型是使用稱爲類型擦除的技術實現的。這意味着泛型類的實例沒有關於泛型的任何信息。考慮這個

List<String> list = new ArrayList<String>(); 
list.toArray(); 
因爲列表

不知道它的泛型類型它只能創建對象[]

0

陣列容器具有相關聯的項目的數據類型,在運行時保留。如果構造一個對象數組,然後添加字符串,這個對象就不會被強制轉換爲字符串[]:

Object[] objArr = new Object[] {"a", "b"}; 
    String[] strArr = (String[]) objArr; //Produces ClassCastException 

您也可以注意到這個數組屬性是如何在運行時使用,當你添加一個不正確類型的項目到一個數組:

String[] strArr = new String[] {"a", "b"}; 
    Object[] objArr = (Object[]) strArr; //Legal this time 
    objArr[0] = 15; //Produces ArrayStoreException 

泛型類型參數在運行時被刪除,因此在JVM不知道具體是什麼類型的數組在運行時創建,當你調用指定者()。

相關問題