2012-11-28 70 views
0

我有一個通用的(我不太清楚,如果這是正確的術語..)方法,將一個對象添加到數組。如何從一個Object []轉換爲另一個數組類型?

@SuppressWarnings("unchecked") 
public static <T>T[] appendArray(T[] a, T b) 
{ 
    T[] temp = (T[])new Object[a.length + 1]; 
    System.arraycopy(a, 0, temp, 0, a.length); 
    temp[a.length] = b; 
    return temp; 
} 

在Eclipse中,這個代碼給了我沒有錯誤,沒有警告(除了抑制「未登記」警告),而且,在我看來,這應該工作。但是,當我嘗試打電話這種方法的東西如..

Integer[] a=new Integer[]{1,2,3}; 
Integer b=4; 
a = appendArray(a, b); 

它給了我一個ClassCastException,在這種情況下,代碼的第2段第3行,我張貼。該錯誤說,[Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;我既沒有看到,也沒有明白爲什麼它會這樣做..我的意思是,我使用的是泛型,那麼爲什麼它會有一個Object[],而不是我在實例化過程中鍵入T?如果它是第4行(當然是代碼的第一位),爲什麼不是拋出異常而不是第二位代碼的第3行?

+0

爲什麼這是downvoted? –

回答

3

而不是使用System.arraycopy,使用Arrays.copyOf,它將數組實例化爲泛型類型。

public static <T> T[] appendArray(T[] a, T b) { 
    T[] temp = (T[]) Arrays.copyOf(a, a.length + 1, a.getClass()); 
    temp[a.length] = b; 
    return temp; 
} 
+0

從技術上講,它不**陣列**。它使用原型(以及類信息)來創建適當類型的數組。 –

2

不能將一個數組轉換爲不同的數組。

數組有一個值類型。這就是[Ljava.lang.Integer;所說的:一個整數數組。這是一個對象數組的不兼容類型。

你有沒有注意到所有的java集合類都使用Object[]?原因是這是數組類型,他們確信他們可以存儲他們的數據。

另請注意,toArray方法的外觀如何。它需要知道你想要出來的數組的類型。它不能從泛型中猜出類型;基本上你需要一個原型對象,然後你需要創建一個適當類型的數組。

+0

但是,除了(T [])new Object [a.length + 1]'之外,不應該有任何投射。所以,爲什麼不是在那裏拋出錯誤而不是在那裏? –

+0

沒有'T []'類型。它不存在。轉換是不正確的,因爲它會在他的情況下*不*使這是一個'整型[]',但它*將*保持爲'Object []'類型的數組。請注意,'(T [])'是通過類型擦除轉換爲Object []而不是'Integer []'。 –

+0

我低估了你的答案,因爲它沒有正確回答問題。從其他答案中可以明顯看出,有幾種方法可以修復OP的代碼,以便在不拋出異常的情況下運行。 – Vulcan

1

泛型和數組不混用!

有一種解決方法。您可以使用特殊Array.newInstance()方法與具體的組件類型創建一個數組對象:

public static <T> T[] appendArray(T[] a, T b) { 
    T[] temp = (T[]) Array.newInstance(b.getClass(), a.length + 1); 
    System.arraycopy(a, 0, temp, 0, a.length); 
    temp[a.length] = b; 
    return temp; 
} 

此代碼不拋出任何錯誤調用時:

public static void main(String[] args) { 
    Integer[] a = new Integer[] { 1, 2, 3 }; 
    Integer b = 4; 
    a = appendArray(a, b); 
    System.out.println(Arrays.toString(a)); 
} 

輸出:

[1, 2, 3, 4] 
+0

好的。這會工作。謝謝。 –

+0

'Arrays.copyOf'基本上結合了'Array.newInstance'和'System.arraycopy'。 – Vulcan

+0

@Vulcan是的,這就是爲什麼我+1你的答案。我不知道'copyOf()' - 很好:) – Bohemian

0

您可以用通用的泛型類型T創建ArrayList並把它作爲一個數組。

@SuppressWarnings("unchecked") 
public static <T>T[] appendArray(T[] a, T b) 
{ 
    T[] temp = new ArrayList<T>(Arrays.asList(a)).toArray(a); 
    System.arraycopy(a, 0, temp, 0, a.length); 
    temp[a.length-1] = b; 
    return temp; 
} 
2

其他答案已經介紹瞭如何重寫代碼的工作,但你的問題下半年仍然存在,所以:

你似乎根本鑄造是什麼誤會。它不會改變任何事物的真實類型。它告訴編譯器「嗨,假裝X類型的引用實際上是Y,相信我,我知道。」

Integer i = (Integer) new Object();

這不會導致Object成爲Integer!當JVM發現你對編譯器撒謊時,它會在運行時拋出一個錯誤。

在你的例子中,錯誤發生的原因比你期望的要晚,'T'是java中的僅編譯時概念。出於運行時間的目的,您可以用Object替換每個'T'。

作爲類型擦除過程的一部分,檢查以查看您所做的聲明是否返回Integer[]的代碼將放入您的方法返回並嘗試進行分配的位置。

+0

好的。這是非常豐富和有益的。謝謝。 –

相關問題