2011-08-29 95 views
1

在我的項目中,我們使用的外部API不是通用的,所以有一個名爲ItemList的類,它的實現爲java.util.List,它包含一個Item對象的列表。然而,在我們的新代碼中,我們表達這種List<Item>,我要編寫能夠既需要ItemListList<Item>, 我試過這種簽名的方法:在傳統代碼中使用泛型

public static void readList(List<?> list) {} 

它工作正常,但問題是有從ObjectItem在此方法中投射,當參數爲ItemList時使用,而List<Item>不需要,是否有更好的方法可以做到這一點?

+0

有趣的是,您認爲Java的「泛型」實現可以使您的代碼「現代化」,因爲它們只是在編譯器最早的便利情況下才拋出去......呵呵再次年輕無辜! – Blindy

+1

@Bindind,可悲的是SO不能投票給你的垃圾評論。 – Sawyer

+0

@Bindind:試着編寫一些現代代碼來處理一個不具有泛型的「傳統」API ......然後用大量的垃圾處理來摧毀你的眼睛。 –

回答

4

如果ItemListList的實現,如果你知道它包含Item情況下,只需將其轉換爲List<Item>。你會得到一個類型安全警告,但它的安全性並不比將ItemList的每個元素投射到Item更安全。

+0

是的,但這可能會要求使用您的API的用戶進行投射以消除警告。 – Sawyer

+2

使用原始類型時,您需要強制轉換。泛型被引入能夠避免它們。由於您的舊API仍然使用原始類型,因此您仍然需要強制轉換。您可以將整個列表轉換爲通用列表,或將每個元素轉換爲Item,這取決於您。但是你將無法避免演員陣容。 –

0

如果我正確讀取API,java.lang.Class:getTypeParameters()看起來很有前途。 嘗試:

if(list.getClass().getTypeParameters().length == 0) { 
    // Code for non-generic 
} else { 
    // Genericized 
} 
1

什麼提供兩個方法 - 一個用於每個參數的類型。至少,你只需要在已討論並接受了著名的地方只有一種類型的安全警示:

public static void readList(List<Item> list) { 
    // do something 
} 

@SuppressWarnings("unchecked") 
public static void readItemList(List<?> list) { 
    readList((List<Item>)list); // Type safety warning tucked away in here 
} 

雖然你沒有類型安全的方法readItemList的名稱是至少一個強有力的暗示他們預計會通過的列表類型的編碼器。

2

您可以編寫新的API來處理List<Item>,因此它可以繼續前進,然後提供靜態轉換方法作爲傳統使用的適配器List<Item> asList(ItemList itemList) ?這樣你就可以隔離難以檢查的轉換髮生的地方。