通用类在Java 6中编译,但不在Java 7中编译

Bri*_*ian 17 java generics collections java-6 java-7

我在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);
}
Run Code Online (Sandbox Code Playgroud)

但在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
Run Code Online (Sandbox Code Playgroud)

对于记录,添加任何类型的覆盖都不起作用.我尝试明确覆盖Map.put,但错误仍然出现.更改my的返回类型put是没有意义的,因为此错误阻止了可能发生的错误,并且如果此错误得到修复,那么这两个方法无论如何都不会具有相同的名称/参数签名.

我想我可能会尝试对Java 6进行一些反思,看看实际的参数类型最终会出现在Java 6的编译字节码中.很明显,两种Java 7方法都被删除了put(Object, Object).一旦我这样做,我会在这里发布反射结果.

在此期间,我的临时解决办法将是多么重命名putputSingle,但这种新的行为是否正确?Java 7中某些部分的泛型规范是否发生了变化,导致旧的Java 6行为错误?或者这是Java 7编译器中的错误?

提前致谢.

编辑:我运行了反射代码.看看我的答案如下.

ass*_*ias 19

我认为这是1.6中的一个错误,修正了1.7.摘自此页面:

概要:类不能定义具有相同擦除签名但具有两种不同返回类型的两种方法
描述:无论返回类型是否相同,类都无法定义具有相同擦除签名的两种方法.这是从JLS,Java SE 7 Edition,第8.4.8.3节开始的.JDK 6编译器允许具有相同擦除签名但返回类型不同的方法; 此行为不正确,已在JDK 7中修复.
示例:

class A {
   int m(List<String> ls) { return 0; }
   long m(List<Integer> ls) { return 1; }
}
Run Code Online (Sandbox Code Playgroud)

此代码在JDK 5.0和JDK 6下编译,在JDK 7下被拒绝.