generics与&-operator和命令的含糊不清

我有一个奇怪的Javagenerics模糊行为,我无法解释:

课堂上的3种方法:

public static  void method(E val) {} public static  void method(E val) {} public static  void method(E val) {} 

编译好。

但那些没有(歧义违规):

 public static  void method(E val) {} public static  void method(E val) {} public static  void method(E val) {} 

(ClassA,ClassB,ClassC都是完全独立的接口!)

由于类型擦除,编译器需要为编译方法中的参数类型选择静态已知类型。

为此,它使用约束列表中的第一个类型。

在第一个示例中,这会为每个方法生成一个唯一类型,因此它会编译为

 public static method(ClassA val); public static method(ClassC val); public static method(ClassB val); 

这是完全合法的(除了您缺少的退货类型); 它使用三种不同的参数类型创建三个重载。

在第二个示例中,这会产生歧义:

 public static method(ClassA val); public static method(ClassB val); public static method(ClassB val); 

这是不合法的,因为最后两个方法具有相同的签名。

规范明确记录了这种行为。

通过尝试从每个重载中选择单个约束类型使得没有冲突,这可能是合法的,但对于较大的约束列表,这将是复杂且缓慢的。
该规范可能会说:

如果它用于擦除参数列表中的类型,则选择在通用方法中擦除类型变量,使得该方法的每个重载在擦除后产生唯一的签名。
如果没有擦除组合将导致唯一签名,则会出现歧义错误。

我怀疑这个问题出现在NP中。

它在JLS#4.6中定义:

类型变量的擦除是其最左边界的擦除。

如果两个方法具有相同的擦除,编译器会给出错误 。