[英]In Java is it possible to create a type-safe Map of classes to instances of their class?
我想創建一個 map,它使用 class 作為鍵來返回該 class 的實例。 就像是:
<T> Map< Class<T>, T > instanceMap = new HashMap< Class<T>, T > ();
instanceMap.put( Boolean.class, Boolean.TRUE );
instanceMap.put( String.class, "asdf" );
instanceMap.put( Integer.class, 11 );
Boolean b = instanceMap.get( Boolean.class );
Integer i = instanceMap.get( Integer.class );
String s = instanceMap.get( String.class );
這可能嗎? 我有一種感覺,不,這不是因為我不能指出T
是一個泛型類型,而不是一個名為“T”的 class。 感覺有點像“高階泛型”。
編輯:我知道我可以嘗試擴展 Map 並實現我自己的包裝器等,但我特別詢問是否僅使用 Java 的通用支持來執行此操作。 我對這個想法而不是這個特殊案例更感興趣。
編輯2:如下所述,這是問題的重復(或更具體地說是子案例): Java map,其值受鍵的類型參數限制。 如果我能找到 eloquent 這樣的措辭,我可能會找到答案,而不是發布這個。
你的意思是這樣的?
public class Favorites {
private Map<Class<?>, Object> favorites =
new HashMap<Class<?>, Object>();
public <T> void setFavorite(Class<T> klass, T thing) {
favorites.put(klass, thing);
}
public <T> T getFavorite(Class<T> klass) {
return klass.cast(favorites.get(klass));
}
public static void main(String[] args) {
Favorites f = new Favorites();
f.setFavorite(String.class, "Java");
f.setFavorite(Integer.class, 0xcafebabe);
String s = f.getFavorite(String.class);
int i = f.getFavorite(Integer.class);
}
}
參見參考: Java map 值受鍵的類型參數限制
據我了解,您是說在創建此 map 之后,您想用類似...的內容填充它
f.put(String.class, "Hello");
f.put(Integer.class, new Integer(42));
f.put(x.getClass(), x);
等等對吧?
在那種情況下,我認為答案是否定的,你不能用 generics 做到這一點。 Generics 說,對於 class 的給定實例——在這種情況下是 map——您正在指定適用的類型。 所以如果你說new HashMap<String,Integer>;
,您是說針對此 map 的所有操作都將使用作為字符串的鍵和作為 integer 的值。 但這不是您在這種情況下想要做的。 您希望能夠將任何類型的 object 放入 class,然后根據 object 的類型限制可接受的密鑰類型。 這不是 generics 的工作方式。 它們不是彼此之間的關系,它們對於任何給定實例都是常數。
當然,您可以將這樣的 map 創建為new HashMap<Class,Object>;
. 這不會強制 class 成為相應 object 的 class,但它允許您輸入這些值。
除此之外,我認為你需要一個包裝器。 我是否應該指出包裝器的 put 只需要一個參數,因為它可能通過對其執行getClass()
來確定參數的 class,不需要告訴它?
在您的示例中,每個鍵/值的T
必須不同,而對於 generics,每個鍵/值的T
必須相同。 所以不,使用 generics 是不可能的。 (但當然可以通過強制轉換和/或不使用泛型來實現)
JsonObject 可能是一個選項。 您可以將任何您喜歡的值作為 jsonobject 的值。 您需要的是 package org.json.JSONObject。 但是,您可能無法將 foreach 與 JSONObject 一起使用,但是有一些替代方法 如何迭代 JSONObject?
Map<T, U>
的點是 map T's to U's。 T 和 U 可以是任意的 class (假設沒有通配符),但是一旦確定了就不能改變了。 在您的情況下,您想要一個根據您使用的鍵返回不同 class 的映射,這顯然是不同的。
go 關於這個的通常方法是讓 U Object
,因為你可以 go 提前並將它投射到你需要的任何東西。 但這當然破壞了 generics 應該提供的類型安全性。
簡而言之,如果不編寫某種包裝器,我認為這是不可能的。
創建實例時, T
必須設置為某些特定類型,因此您無法使用put
方法向 map 添加不同的類型。 另一方面,泛型方法在調用它們時會設置其類型 arguments,從而允許您做您想做的事情。
Guava有一個ClassToInstanceMap類型,它使用通用方法來處理安全地將實例放入 map 並取出它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.