簡體   English   中英

我可以在 Java 的泛型類型上調用 .class 嗎?

[英]Can I call .class on a generic type in Java?

我想知道Java中是否有辦法做類似的事情

Class c = List<String>.class;
Class c2 = List<Date>.class;

我需要這樣的東西來創建一個存儲類名(具有泛型類型)和我以后可以查找的相應對象的映射。 例如,

Map<Class, Object> dataMap = new HashMap<Class, Object>();
dataMap.put(c, listOfStrings);
dataMap.put(c2, listOfDates);

由於運行時類型擦除,這是不可能的嗎?

你不能這樣做,但你可以使用與 Guice 對TypeLiteral相同的方法來實現你的總體目標。 如果您已經在使用 Guice,我建議您直接使用它 - 否則,您可能想要創建自己的類似類。

本質上,這個想法是指定類型參數的泛型類型的子類直接保留該信息。 所以你寫了這樣的東西:

TypeLiteral literal = new TypeLiteral<List<String>>() {};

然后你可以使用literal.getClass().getGenericSuperclass()並從中獲取類型參數。 TypeLiteral本身不需要有任何有趣的代碼(我不知道它在 Guice中是否有任何東西,出於其他原因)。

不,這是不可能的。 您甚至不能在代碼中引用List<String>.class - 它會導致編譯錯誤。 List只有一個類對象,稱為List.class

由於運行時類型擦除,這是不可能的嗎?

正確的。

順便說一句,這是泛型類型,而不是帶注釋的類型。

更新

再想一想,您可以通過稍微調整 Josh Bloch 的類型安全異構容器(在Effective Java 2nd Ed.,Item 29 中發布)來獲得與上面的 Map 相當接近的東西:

public class Lists {
    private Map<Class<?>, List<?>> lists =
            new HashMap<Class<?>, List<?>>();

    public <T> void putList(Class<T> type, List<T> list) {
        if (type == null)
            throw new NullPointerException("Type is null");
        lists.put(type, list);
    }

    public <T> List<T> getList(Class<T> type) {
        return (List<T>)lists.get(type);
    }
}

getList中的強制轉換未選中,發出警告,但恐怕我們無法避免這種情況。 但是,我們知道為類X存儲的值必須是List<X> ,因為這是由編譯器保證的。 所以我認為演員陣容是安全的(如果你遵守規則,也就是說 - 即永遠不要使用普通的非泛型Class參數調用putList ),因此可以使用@SuppressWarnings("unchecked")來抑制它。

你可以像這樣使用它:

Lists lists = new Lists();
List<Integer> integerList = new ArrayList<Integer>();
List<String> stringList = new ArrayList<String>();
...

lists.putList(Integer.class, integerList);
lists.putList(String.class, stringList);
List<Integer> storedList = lists.getList(Integer.class);

assertTrue(storedList == integerList);

這是不可能的,因為你正在嘗試。
但是您可以裝飾這些列表並創建一個MyListDatesMyListString並將它們存儲在哈希圖中

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM