2016-02-06 71 views
0

我有一個LinkedList<T>其中包含Object toArray()方法:的Java /泛型/ ClassCastException異常

public Object[] toArray() 
{ 

    Object[] array = new Object[size]; 

    int c=0; 
    for(Node<T> i = first;i != null;i=i.next) 
    { 
     array[c++] = i.data; 
    } 

    return array; 
} 

我想我的排序與LinkedList的泛型方法:<T extends Comparable> void sort (List<T> list)。要排序列表,我必須代表他們作爲數組中此方法:

T[] elements = (T[])list.toArray();` 

然而,我在這行獲得ClassCastException,我不知道爲什麼。由於該方法的泛型類型等同於返回數組中的元素運行時類型,因此這種轉換不是謊言!

+0

你能提供更多的代碼嗎?它很難說這樣的東西 – Infested

+0

'List#toArray()'返回'Object []',而不是'T []'(數組保持它的元素的類型,在這種情況下它是'Object')。要對列表進行排序,請使用'Collections.sort(list)'或在'toArray(T [] destination)中提供'T []' –

+0

爲什麼不直接對列表進行排序而不使用java.util將其更改爲數組。作品集:'Collections.sort(list)'? –

回答

1

toArray()返回Object[]。類型信息丟失,您無法將其轉換回T []。如果您想保留類型信息,您可以使用以下內容。然後你給這個方法一個預先填充的數組。如果您不給任何東西 - toArray將創建一個新的Object[]

T[] elements = list.toArray(new T[list.size()]); 

只是填充陣列(另一個寫作風格):

T[] elements = new T[list.size()]; 
list.toArray(elements); 

,或者如果你使用Java 8:

T[] elements = list.stream().toArray(T[]::new); 
+0

但是,編譯器說我不能創建通用數組。 –

+0

當然,T只是爲了示範。在外面,你調用toArray方法的地方,你必須給出一個像String或Integer這樣的真實類型。在toArray方法中,使用泛型。 –

1

您應該使用T[] toArray(new T[list.size()])來代替。無需投射。

+0

爲什麼我的演員陣容? –

+0

@BenyBosko因爲'T []'是'T's「的數組,而不是'Object'的數組」。類型擦除不適用。 –

+0

但我認爲底層類型是T而不是返回數組中的Object!對不起,目前尚不清楚。 –

2

的方法LinkedList.toArray()創建類型Object[]的新數組。它不創建類型T[]的新陣列。這很重要,因爲即使數組僅包含T的實例,也不能將該數組分配給T[]類型的變量,因爲數組本身的類型爲Object[]。您可以重現此錯誤與下面的代碼:

String[] array = (String[]) new Object[0]; 

如果我理解正確的話,你要到列表轉換成一個陣列,能夠實現自己的搜索功能。給定一個List<T>,其中包含T類型的元素,您希望將此列表轉換爲T[]類型的數組。但是,您不能簡單地調用new T[list.size()],因爲Java在編譯時丟失了泛型類型信息。要創建正確類型的數組,您需要使用反射方法Array.newInstance()

下面是一個例子:

@SuppressWarnings("unchecked") 
private <T extends Comparable<T>> void sort(List<T> list, Class<T> clazz) { 
    T[] array = list.toArray((T[]) Array.newInstance(clazz, list.size())); 
    // sort array and write result to the list 
} 

這裏的用法:

List<String> list = new LinkedList<String>(); 
    // populate the list 
    sort(list, String.class); 
    System.out.println(list); // -> the sorted list 
+0

感謝您的額外工作。我會在這些東西做一些進一步的研究 –

+0

總是樂於幫助。關鍵字是**類型擦除**。 –