2011-06-04 181 views
2

我有這樣的ConcurrentMap的包裝類如下:Java泛型和界類型

public MapWrapper<K, V> implements ConcurrentMap<K, V> { 

    private final ConcurrentMap<K, V> wrappedMap; 

    ... 
    @Override 
    public void putAll(Map<? extends K, ? extends V> map) { 
     wrappedMap.putAll(map); // <--- Gives compilation error 
    } 
    ... 
} 

標線觸發以下編譯錯誤:

method putAll in interface java.util.Map<K,V> cannot be applied to given types; 
required: java.util.Map<? extends capture#5 of ? extends K,? extends capture#6 of ? 
    extends V> 
found: java.util.Map<capture#7 of ? extends K,capture#8 of ? extends V> 
reason: actual argument java.util.Map<capture#7 of ? extends K,capture#8 of ? extends V> 
    cannot be converted to java.util.Map<? extends capture#5 of ? extends K,? extends 
    capture#6 of ? extends V> by method invocation conversion 

我懷疑無界通配符是罪魁禍首但我無法更改方法簽名,因爲它是從ConcurrentMap接口繼承的。有任何想法嗎?

+4

你正在使用什麼樣的編譯器(同樣,IDE可能有它自己的,就像Eclipse一樣)?我設法在Eclipse中編譯並使用javac(1.6);你也可以嘗試轉換wrappedMap.putAll((Map )m); – 2011-06-04 21:20:31

+1

只是試圖重現你有的代碼和...一切工作正常。我創建了一個模擬'MapWrapper '並實例化'。然後用'HashMap 調用'putAll'方法,一切正常。 (使用eclipse和Java 1.6) – 2011-06-04 21:29:22

+0

謝謝亞瑟,我發現了錯誤。事情是,包裝圖不是一個真正的ConcurrentMap,而是一個實現該接口的類。我在代碼中混合了兩種不同的東西,但由於涉及到泛型,錯誤消息確實沒有太大的幫助。 – teto 2011-06-04 21:51:30

回答

0

讓我們看看到的putAll

public void putAll(Map<? extends K, ? extends V> m) 

的簽名......和錯誤,你有:

cannot be converted to java.util.Map<? extends capture#5 of ? extends K,? extends 

那麼原因你不能這樣做,這是Java中繼承樹合併的限制。

也許,會更好地編寫自己的putAll方法的實現。

謝謝,希望它能幫助你。

+0

我不確定「繼承樹合併的限制」是什麼意思,但如果您閱讀了註釋,則OP發現錯誤是由於一個無關的問題造成的。 – 2012-03-31 21:09:38