Неоднозначность дженериков с помощью & -оператора и порядка

У меня странное поведение двусмысленности Java-дженериков, которое я не могу объяснить:

Те 3 метода в классе:

public static <E extends ClassA & ClassB> void method(E val) {}
public static <E extends ClassC & ClassB & ClassA> void method(E val) {}
public static <E extends ClassB> void method(E val) {}

компилировать.

Но это не (нарушение двусмысленности):

public static <E extends ClassA & ClassB> void method(E val) {}
public static <E extends ClassB & ClassC & ClassA> void method(E val) {}
public static <E extends ClassB> void method(E val) {}

(ClassA, ClassB, ClassC - полностью независимые интерфейсы!)

Ответы

Ответ 1

Из-за стирания типа компилятору необходимо выбрать статически известный тип для типа параметра в скомпилированном методе.

Чтобы сделать это, он использует первый тип в списке ограничений.

В первом примере это приводит к уникальному типу для каждого метода, поэтому он компилируется в

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.