執行提取表達式重構時,我偶然發現了Eclipse 4.4和Java 8生成45中的一些奇怪行爲,至少對我而言如此。下面的例子顯示了原始的和正確的代碼將提取物重構之前:使用泛型返回類型提取表達式後類型不匹配
import java.util.Map;
import java.util.Set;
public class MyMap<K, V> {
public void putAll(final Map<? extends K, ? extends V> mapToCopy) {
for (Map.Entry<? extends K, ? extends V> entry : mapToCopy.entrySet()) {
}
}
}
Eclipse的重構的結果是這樣的,導致下面的錯誤消息指entrySet
在讀訪問循環聲明:
public void putAll(final Map<? extends K, ? extends V> mapToCopy) {
Set<?> entrySet = mapToCopy.entrySet();
for (Map.Entry<? extends K, ? extends V> entry : entrySet) {
^^^^^^^^
}
}
Type mismatch: cannot convert
from element type capture#3-of ?
to Map.Entry<? extends K,? extends V>
我改變了entrySet
聲明的類型Set<Map.Entry<? extends K, ? extends V>>
。這次,錯誤在聲明的初始化程序中顯示,說:
public void putAll(final Map<? extends K, ? extends V> mapToCopy) {
Set<Map.Entry<? extends K, ? extends V>> entrySet = mapToCopy.entrySet();
^^^^^^^^^^^^^^^^^^^^
for (Map.Entry<? extends K, ? extends V> entry : entrySet) {
}
}
Type mismatch: cannot convert
from Set<Map.Entry<capture#1-of ? extends K,capture#2-of ? extends V>>
to Set<Map.Entry<? extends K,? extends V>>
由於原始代碼的確編譯,所以我有點困惑。也許有人可以幫助我並給出解釋?提前致謝!
請注意'Set <?擴展Map.Entry <?延伸K,?擴展V >> entrySet = mapToCopy.entrySet(); '會工作。 [JLS第14.4.2節](http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.14.2)討論了增強中「Iterable」的翻譯爲'聲明。另請參閱[本答案](http://stackoverflow.com/a/16753901/5065475) –
@AndyBrown:請您詳細說明「請注意,[...]將工作」,請。我需要修改什麼才能使其工作? – Marcus
在java8中,還可以嘗試'map.forEach((key,value) - > {...})'。鍵/值被推斷爲適當的類型,如K/V的某些未知子類型。如果我們規定類型 - 'map.forEach((K key,V value) - > {...}),那麼API也是足夠靈活的' – ZhongYu