2015-12-18 95 views
2

我有兩個地圖Something1Something2。兩者都擴展類Something與泛型和變量賦值問題

Map<Class<? extends Something1>, String> m1 
Map<Class<? extends Something2> ,String> m2 

我想創建一個更通用的地圖m3,而我可以分配m1m2這樣的:

Map<Class<? extends Something>, String> m3 = m1; 

但是我得到以下異常:

Type mismatch: cannot convert from Map<Class<? extends Something1>, String> to Map<Class<? extends Something>, String> 

我也嘗試使用Class<?>,但似乎沒有工作。

我在做什麼錯?

+3

閱讀本回答 - http://stackoverflow.com/a/19220458/1679863,瞭解多層次泛型如何工作。之後,您將能夠理解將第三張地圖更改爲:Map <?擴展Class <?擴展Something>,String> = m1;'會工作。 –

+1

非常感謝!這解決了我的問題 – user1534960

回答

2

這是不可能的。考慮以下內容:

Map<Class<? extends Something1>, String> m1 = new HashMap<>(); 
m1.put(Something1.class, "Something1"); // OK 
m1.put(Something2.class, "Something2"); // Error 

所以,你不能把Something2作爲關鍵。

其他各地的道:

Map<Class<? extends Something2>, String> m2 = new HashMap<>(); 
m2.put(Something1.class, "Something1"); // Error 
m2.put(Something2.class, "Something2"); // OK 

在這裏,你不能把Something1的關鍵。

但是,如果您創建使用基類作爲通配符的版本,它將起作用。看看這個:

Map<Class<? extends Something>, String> m = new HashMap<>(); 
m.put(Something1.class, "Something1"); // OK 
m.put(Something2.class, "Something2"); // OK 

你的問題是,然後你試圖分配一個更具體的類型到泛型類型。像這樣:

m = m1; // Boom, but why? 

爲什麼不行。嗯,這是因爲如果你讓你的分配將能夠做到這一點:

m.put(Something2.class, "Something2"); 

這顯然不會是好的,因爲那麼你會把Something2作爲一個Something1型地圖的關鍵。

0

非通配符類型參數必須完全相同才能兼容。 Class<? extends Something1>Class<? extends Something>(即使一個是另一個的子類型)並不完全相同,因此一個Map與另一個的Map不兼容。

如果你想有一個類型,它可以接受Map s的不同類型的參數,你需要在頂層一個通配符(但請注意,這將有效地使Map只讀):

Map<? extends Class<? extends Something>, String> m3 = m1;