[英]Java / Generics / Array problems
我想最終了解泛型和數組之間的關系,因此我將基於ArrayList<T>
提供一個與我不一致的示例:
Object[] elementData = new Object[size];
這是通用列表元素的存儲位置。
public void add(T element){ elementData[size++] = element; }
public T get(int index) { return (T)elementData[index] }
完全有效。 我可以找出底層的<T>
對象,但是包含對這些對象的引用的數組是Object
。
與此相反:
public Object[] toArray()
{
Object[] result = new Object[size];
for(int i = 0;i<size;i++)
{
result[i] = elementData[i];
}
return result;
}
我無法將返回數組中的元素強制轉換為它們的真實類型,但是整個設置是相同的:一個Object
數組,其中包含對<T>
對象的引用。 嘗試將元素轉換為實型時出現ClassCastException
錯誤。
如果查看Collection
接口,則會發現有2個toArray()
方法:
Object[] toArray()
返回一個包含此集合中所有元素的數組。
<T> T[] toArray(T[] a)
返回包含此集合中所有元素的數組; 返回數組的運行時類型是指定數組的運行時類型。
這樣做的原因是您無法創建通用數組,因此僅返回Object []。
為您的toArray()
創建通用方法很簡單:
public <T> T[] toArray(T[] arr)
{
T[] result = arr.size == size ? arr : (T[])java.lang.reflect.Array
.newInstance(arr.getClass().getComponentType(), size);
for(int i = 0;i<size;i++)
{
result[i] = elementData[i];
}
return result;
}
數組在運行時知道其組件類型。 因此,要創建數組,需要在運行時提供組件類型。 但是,在您的情況下,您在運行時不知道T
因此,您不能創建真正是T[]
。 您只能返回Object[]
,或依靠某人給您一些東西,您可以在運行時從中獲得類型T
您可以將返回數組中的元素轉換為它們的實型。 但是您不能將數組轉換為T []
Java中的數組在引入泛型的Java 5之前就存在。 因此,數組不依賴於泛型,這就是為什么我們經常在API中使用集合而不是數組的原因。 因此,Collection最終可以轉換為Collection,但是Object []無法轉換為另一個數組T [],它將是另一個不兼容的類型。
我認為這與以下事實有關:數組是協變的,因此您可以從T[]
Object[]
為Object[]
,因為Object
可以完成T
可以做的任何事情,但是反之則沒有意義, Object
不能盡一切T
即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.