2015-09-04 56 views
4

類型下面的代碼調用駱駝交易所指定的類對象

List<Message> list = oldExchange.getProperty("p",List.class);

setProperty方法的目的是,我找回我以前存儲的反對Exchange實例的List對象。由於這段代碼站立,我得到一個編譯器警告(類型安全:類型列表的表達式需要unchecked轉換符合列表)。

我知道我可以通過添加@SuppressWarnings("unchecked")註釋使其消失,但是有沒有辦法通過更改List.class的聲明來修復它?

getProperty方法具有以下簽名 <T> T getProperty(String name, Class<T> type)

回答

1

不幸的是,您的演員陣容不安全,因爲雖然您知道返回的對象具有List類型,但您無法確定此列表中的所有元素是否具有Message類型。所以,你可能會得到意想不到的ClassCastException很久以後,當你喜歡寫東西Message m = list.get(0);

爲了讓你的代碼強健你必須檢查所有現有列表的元素,那麼你可以做的選中投這樣的:

public static <T> List<T> checkElements(List<?> list, Class<T> elementClass) { 
    for(Object e : list) { 
     elementClass.cast(e); // throw CCE on wrong element 
    } 
    @SuppressWarnings("unchecked") 
    List<T> result = (List<T>)list; 
    return result; 
} 

@SuppressWarnings在這個方法中仍然是必需的,但它是「庫」方法,所以在這裏沒關係。然而,在業務代碼你現在可以使用:

List<Message> list = checkElements(oldExchange.getProperty("p",List.class), Message.class); 

這種方法的缺點是,它需要一些時間來檢查每一個元素的類型。如果您100%確定您擁有正確的列表,那麼只需在原始代碼中使用@SuppressWarnings即可。

2

不幸的是,這不能做 - 沒有泛型類型無類文字表達。

如果你有很多你的代碼,這樣的電話,你可能要創建一個實用的方法來壓制的警告只在一個地方:

@SuppressWarnings("unchecked") 
static <T> T myGetProperty(String name, Class<?> type) { 
    return (T) getProperty(name, type); 
} 

那麼這個電話打進來而不發出警告:

List<String> listOfStrings = myGetProperty("a", List.class); 

但是,您需要記住,確實未經檢查因此您無法確定列表中的元素是否爲字符串。