[英]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.