[英]unchecked warning on Class<Collection>
假設我具有以下方法,該方法可用於創建指定的給定類型的集合。
private static Collection<?> void create(Class<? extends Collection<?>> cls) {
return cls.newInstance();
}
如果在運行時傳遞cls參數,那么這一切都很好:
List<String> list = new LinkedList<String>();
create(list.getClass());
但是,如何在沒有未經檢查的警告的情況下在代碼中調用此方法? 假設我想執行以下操作:
create(LinkedList.class);
它將抱怨未定義create(Class),嚴格來說,這是正確的,因為List不是#capture的Collection,但是我如何使它工作?
非常感謝!
尼爾·古夫特(Neal Gafter) 在這里幾乎完全討論了這個問題。 解決方法是使用超級類型令牌 。 我相信,Guice就是用來維護通用類型信息的。
基本上,這是一個額外的類,可以用來表示一個類型,而不是使用Foo.class
。 您可以這樣使用它:
TypeReference<LinkedList<String>> x = new TypeReference<LinkedList<String>>() {};
create(x);
請注意,您嘗試使用原始類型LinkedList
仍然會導致編譯器抱怨,這是故意的-使用原始類型時,您基本上選擇了類型安全。 但是,此方案允許您以其他方式難以表達的泛型類型。
我們這里有兩種通用類型,一種是集合的子類型,一種是集合的元素類型。 以下代碼可以工作:
private static <C extends Collection<E>, E>
C create(Class<C> cls) throws Exception
{
return cls.newInstance();
}
使用示例。 沒有警告。
Class<LinkedList<String>> clazz = ...;
LinkedList<String> result = create(clazz);
現在的問題變成我們如何獲得clazz
? 您必須非常說服編譯器:
List<String> list = new LinkedList<String>();
clazz = (Class<LinkedList<String>>)list.getClass();
clazz = (Class<LinkedList<String>>)(Class<?>)LinkedList.class;
我們可以使用一種實用方法來簡化類型轉換:
public static <C extends Collection, E, T extends Collection<E>>
Class<T> type(Class<C> classC, Class<E> classE)
{
return (Class<T>)classC;
}
//usage:
clazz = type(LinkedList.class, String.class);
result = create(clazz);
有趣的是遞歸的:
Class<LinkedList<LinkedList<String>>> clazz2;
LinkedList<LinkedList<String>> result2;
clazz2 = type(LinkedList.class, clazz);
result2 = create(clazz2);
但是在某個時候,我們必須停止這場愚蠢的比賽。 泛型打字應該幫助我們,而不是折磨我們。 當它變得太麻煩並且使我們的程序無法閱讀時,請將其刪除。 使用我們幸福生活多年的該死的原始類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.