它是:
add(i.toArray(new Animal[i.size()]))
List.toArray返回Object[]
,無論在列表中的參數的類型:即使你可能寫new List<String>().toArray()
,你會得到一個Object[]
。但是,version of toArray that takes an array to fill會返回一個正確類型的數組:如果您編寫了new List<String>().toArray(new String[0])
,您將得到一個String[]
。請注意,您傳入的數組的大小甚至不必與列表的大小相匹配,儘管確保它的確很好。
這最終是由於泛型的一個輕度棘手的功能。乍一看,你可能會認爲String[]
和List<String>
對於它們的基本類型意味着類似的東西 - 一個是字符串數組,另一個是字符串列表。
然而,他們其實是非常不同的。
數組是一種語言原語,並且它的類型已經烘焙到其中。如果您使用了十六進制編輯器並在JVM的內存中查看了一個數組實例,那麼您將能夠找到(位於附近的某個地方)所保存對象類型的記錄。這意味着如果你拿一個未知組件類型的數組的實例,你可以使用find out what that type is。相反,這意味着如果你打算去create an instance of an array,你需要知道你想要什麼組件類型。
的List
,在另一方面,使用泛型,這在Java中與type erasure實施,這意味着,粗略地講,它是什麼,存在於編譯器,而不是在運行時(編譯器可以檢查你做對了,但JVM不能)。這導致了一個簡單而有效的實現(一個足夠簡單的已經被添加到pre-generics Java而無需更改JVM),但它有一些缺點 - 特別是在運行時,無法告訴類型參數在泛型類的任何特定實例上,因爲類型參數只存在於編譯器中。由於List
實例需要處理toArray()
,因此它唯一能做的就是創建一個Object[]
。它只是不知道使用更具體的類型。看這個
的一種方法是,數組有一個類型參數作爲自己類的一部分,而List
■找一個類型參數作爲自己類型的一部分,因爲對象有類,但變量具有類型,您不能從一個對象中獲取List
的類型實參,只能從保存對象的變量中獲得(另外,您也不能從包含數組的變量中獲取數組的類型實參(考慮Object[] array = new String[0];
),但這並不重要,因爲變量可以讓你獲得一個對象 - 除非它爲空)。
熬下來代碼,問題是:
public <E> E[] createSimilarlyTypedArray(List<E> list) {
Class<E> componentType = list.???; // there is no way to do this
return Arrays.newInstance(componentType, list.size());
}
我不明白這個問題。你創建了自己的方法'add(Animal ...)',但是你調用ArrayList.add(Object)而不是你自己的方法。這是爲什麼?請使用代碼的上下文編輯問題。你的'add'方法中的代碼塊是什麼?如果你唯一的問題是你不能將Object []轉換爲Animal [],那麼按照@Tom的回答。 – aalku
只是對將來的說明:如果您有編譯器錯誤,請複製完整的錯誤消息以及與此消息相關的源代碼行。 –