Ответ 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.