执行提取表达式重构时,我偶然发现了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