簡體   English   中英

Java泛型難題-獲取泛型類型的對象的類/類型,以便以后可以確保類型

[英]Java Generics puzzle - Get the class/type of object of generic type so that you can ensure the type later

看這堂課。

它有什么作用? 它是一個HashMap,其中鍵是Class對象,而值是Hashmap,其鍵和值是由Class對象定義的類型。

假設您要使用方法add(K obj),這將是一種便捷的方法。 當您還可以讓用戶僅將實例本身傳遞給用戶時,為什么還要強迫用戶鍵入add(Person.class,personInstance)-代碼應能夠獲取對象的類並將實例置於鍵為對象的類別。 但是我不能。 add(K obj)便捷方法無法編譯:

public class TypedHashmap extends HashMap<Class, HashMap> {

    public <K> HashMap<K, K> getHashMap(Class<K> type) {
        return (HashMap<K, K>) getOrDefault(type, new HashMap<K, K>());
    }

    public <K> void add(K obj, Class<K> type) {
        HashMap<K, K> toModify = getHashMap(type);
        toModify.put(obj, obj);
    }

    public <K> void add(K obj) {
        add(obj, obj.getClass());
    }
}

編譯錯誤:

在此處輸入圖片說明

我可以看到Java不確定obj.getClass()類型。 但是我不明白為什么。 是否因為不能確保該類實際上不是擴展K的東西? 這里有什么問題? 可以以某種方式解決此問題嗎?

泛型是確保類型安全的工具。

設計API的方式在這種級別上並不安全,這就是為什么會出現此錯誤的原因。

public <K> void add(K obj) {
    add(obj, (Class<K>) obj.getClass());
}

是一種明確表明不能在此處確保鍵入saftey的方法。 或者只是做一個

public void add(Object obj) {
    add(obj, (Class<Object>) obj.getClass());
}

這將為您提供相同級別的類型安全性(無)。

如果您想要一個稍微干凈的解決方案(不要在較簡單的add函數中強制轉換),則也必須修改其他add函數。

public <K> void add(K obj, Class<? super K> type) {
    HashMap<K, K> toModify = getHashMap(type);
    toModify.put(obj, obj);
}

public void add(Object obj) {
    add(obj, obj.getClass());
}

但是最后,我相信您正在實現一種反模式

問題是這樣的:

Number a = new Integer(3);
map.add(a);
map.getHashMap(Number.class).contains(a);

產生假。 整數不在 Number映射中。 因為您的地圖不支持子類型和繼承。

將一個Integer對象添加到列表中。 但是,除非我知道

就編譯器而言, obj.getClass()返回Class<?>類型的實例,並且您沒有帶簽名的方法

void add(K obj, Class<?> type)

你有

void add(K obj, Class<K> type)

這很接近,但並不完全正確。

您沒有使您的類通用,因此所有方法通用都是獨立的(每個K是不同的ANY)。 我想你想要類似的東西

public class TypedHashmap<K> extends HashMap<Class<K>, HashMap<K, Class<K>>> {
    public HashMap<K, Class<K>> getHashMap(Class<K> type) {
        return (HashMap<K, Class<K>>) getOrDefault(type, new HashMap<>());
    }

    public void add(K obj, Class<K> type) {
        HashMap<K, Class<K>> toModify = getHashMap(type);
        toModify.put(obj, type);
    }

    public void add(K obj) {
        add(obj, (Class<K>) obj.getClass());
    }
}

暫無
暫無

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

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