我在Java 6中有一个能够正确编译的接口:
public interface IMultiMap<K, V> extends Map<K, Set<V>> {
public int valueSize();
public boolean put(K key, V value);
public void clear(Object key);
public boolean isEmpty(Object key);
}
不过在Java 7中,这个接口不能编译通过。我在boolean put(K, V)
处得到了编译错误,原因是它的擦除与V put(K, V)
相同。编译器返回的完整错误信息:
error: name clash: put(K#1,V#1) in IMultiMap and put(K#2,V#2) in Map have the same erasure, yet neither overrides the other
public boolean put(K key, V value);
where K#1,V#1,K#2,V#2 are type-variables:
K#1 extends Object declared in interface IMultiMap
V#1 extends Object declared in interface IMultiMap
K#2 extends Object declared in interface Map
V#2 extends Object declared in interface Map
顺便说一句,任何类型的覆盖都行不通。我试过显式重写Map.put
,但错误仍然出现。改变我的put
的返回类型是无意义的,因为这个错误阻止了潜在的错误被达到,如果这个错误被修复了,那么这两个方法也不会有相同的名称/参数签名。
我想我可能会尝试一些 Java 6 上的反射,并看看 Java 6 编译后的实际参数类型是什么。很明显,两个 Java 7 方法都被擦除为put(Object, Object)
。我会在这里发布反射结果。
与此同时,我的临时解决方法将只是将put
重命名为putSingle
,但这种新行为是否正确?Java 7 的泛型规范的某些部分发生了变化,使得旧的 Java 6 行为不正确吗?还是这是 Java 7 编译器的一个 bug?
先谢谢了。
编辑:我运行了反射代码。请查看下面的答案。