2016-11-25 102 views
0

我的目標是實現一個接受類實例的操作,但前提是具體傳遞類繼承自Collection。如何使用泛型正確指定類<?>參數

我在我的代碼上得到編譯器警告,我無法解決。

package com.fun.with.generics; 

import java.util.ArrayList; 
import java.util.Collection; 

public class AcceptTypedClass 
{ 
    // Warning here on 'Collection': ... raw type, references should be parameterized. 
    private static void printCollectionClass(Class<? extends Collection> c) 
    { 
     System.out.println(c.getName()); 
    } 

    public static void main(String[] args) 
    { 
     // Warning here on ArrayList: ... raw type, references should be parameterized. 
     Class<ArrayList> arrayList = ArrayList.class; 
     printCollectionClass(arrayList); 
    } 
} 

我明白的警告信息,但如果我通過添加缺少的類型參數如下圖所示修復警告,我得到一個錯誤。

Class<ArrayList<?>> arrayList = ArrayList.class; 

有人可以解釋一下嗎?問題是如果我可以編寫上面的代碼,以便我不會發出警告(並且代碼有效)?

+1

你有沒有試過Class?擴展集合>'?請注意,進一步向下傳遞'ArrayList',其中'Class'是預期的。 –

回答

0

您可以更改printCollectionClass方法

private static <T extends Collection<?>> void printCollectionClass(Class<T> c) { 
     System.out.println(c.getName()); 
    } 
public static void main(String[] args) { 
     printCollectionClass(ArrayList.class); 
    } 

這裏printCollectionClass將接受類從集合繼承。

+0

很酷。這是解決方案。 (但我承認:爲什麼編譯器現在快樂的簡短解釋會對我有所幫助。) –

0

由於在運行時沒有可用的通用類型信息,所以類作爲通用的「類型令牌」(即在運行時指示特定類型的某種方式)是一個根本不好的選擇。

這是更好地利用兩種:

  • 的類的實例(相應類型的如列表爲空) - 雖然這僅僅是滿足類型安全的編譯器,不提供任何運行時類型信息。
  • 實際的「類型令牌」類,如GSON's TypeTokenGuice's TypeLiteral

    請注意,這兩個類的Javadoc始於:

    表示泛型類型T的Java還沒有提供一種方式來表示泛型類型,所以這個類呢。 ...

    一個GSON類型的令牌,是通過TypeToken一個匿名子類創建:

    TypeToken<ArrayList<String>> typeToken = new TypeToken<ArrayList<String>>() {}; 
    

    子類的行爲烘烤泛型類型信息到typeToken例如,通過typeToken.getClass().getGenericSuperclass()

    請注意,您不能一般這樣做 - 您必須創建具有實際類的子類作爲通用參數,而不是類型變量。

相關問題