爲什麼Collection<E>.toArray()
(非參數化方法)返回Object[]
?爲什麼Collection <E> #toArray()不返回E []?
這是有意識的決定之一嗎?如果想要的話,toArray()
方法不能返回E[]
是否有任何理由?
爲什麼Collection<E>.toArray()
(非參數化方法)返回Object[]
?爲什麼Collection <E> #toArray()不返回E []?
這是有意識的決定之一嗎?如果想要的話,toArray()
方法不能返回E[]
是否有任何理由?
這是因爲在不知道類型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;
}
Java中的泛型是使用稱爲類型擦除的技術實現的。這意味着泛型類的實例沒有關於泛型的任何信息。考慮這個
List<String> list = new ArrayList<String>();
list.toArray();
因爲列表
不知道它的泛型類型它只能創建對象[]
陣列容器具有相關聯的項目的數據類型,在運行時保留。如果構造一個對象數組,然後添加字符串,這個對象就不會被強制轉換爲字符串[]:
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不知道具體是什麼類型的數組在運行時創建,當你調用指定者()。
類型擦除是原因。 java不知道T在運行時是什麼 - 因此它不能創建適當類型的數組。另一種toArray的「typesafe」變體需要一個「原型」數組,它具有可以複製的正確類型(在編譯時固定!)。 – Pyranja 2013-02-23 07:24:49
這是歷史。該方法早於泛型,並保持其現有形式以避免打破傳統代碼。 – Perception 2013-02-23 07:25:21
我不太確定。我沒有辦法在該方法中獲得'E'類。 – 2013-02-23 07:28:29