Обобщенные методы Java в обобщенных классах

Если вы создаете универсальный класс в Java (класс имеет параметры универсального типа), можете ли вы использовать универсальные методы (метод принимает параметры универсального типа)?

Рассмотрим следующий пример:

public class MyClass {
  public <K> K doSomething(K k){
    return k;
  }
}

public class MyGenericClass<T> {
  public <K> K doSomething(K k){
    return k;
  }

  public <K> List<K> makeSingletonList(K k){
    return Collections.singletonList(k);
  }
}

Как и следовало ожидать с универсальным методом, я могу вызватьdoSomething(K) в случаяхMyClass с любым объектом:

MyClass clazz = new MyClass();
String string = clazz.doSomething("String");
Integer integer = clazz.doSomething(1);

Однако, если я попытаюсь использовать экземплярыMyGenericClass без указав общий тип, я звонюdoSomething(K) возвращаетObjectнезависимо от того, чтоK было передано в:

MyGenericClass untyped = new MyGenericClass();
// this doesn't compile - "Incompatible types. Required: String, Found: Object"
String string = untyped.doSomething("String");

Как ни странно, он будет компилироваться, если тип возвращаемого значения является универсальным классом - например,List<K> (На самом деле это можно объяснить - см. Ответ ниже):

MyGenericClass untyped = new MyGenericClass();
List<String> list = untyped.makeSingletonList("String"); // this compiles

Кроме того, он будет компилироваться, если типовой класс набирается, даже если только с подстановочными знаками:

MyGenericClass<?> wildcard = new MyGenericClass();
String string = wildcard.doSomething("String"); // this compiles

Есть ли веская причина, почему вызов универсального метода в нетипизированном универсальном классе не должен работать?

Есть ли какая-нибудь хитрая уловка, относящаяся к универсальным классам и универсальным методам, которые мне не хватает?

РЕДАКТИРОВАТЬ:

Для пояснения я бы ожидал, что нетипизированный или необработанный универсальный класс не будет учитывать параметры типа универсального класса (поскольку они не были предоставлены). Однако, для меня неясно, почему нетипизированный или необработанный типовой класс будет означать, что универсальные методы не соблюдаются.

Оказывается, этот вопрос уже поднимался на SO, ср.этот вопрос, Ответы на это объясняют, что когда класс не типизирован / находится в необработанном виде,все дженерики удаляются из класса, включая типизацию дженериков.

Однако на самом деле нет объяснения, почему это так. Итак, позвольте мне уточнить мой вопрос:

Почему Java удаляет типовые методы, типизированные для нетипизированных или универсальных классов необработанного типа? Есть ли для этого веская причина или это был просто недосмотр?

РЕДАКТИРОВАТЬ - обсуждение JLS:

Было предложено (в ответ на предыдущий вопрос SO и на этот вопрос), что это рассматривается вJLS 4.8который гласит:

Тип конструктора (§8.8), метода экземпляра (§8.4, §9.4) или нестатического поля (§8.3) M необработанного типа C, который не унаследован от его суперклассов или суперинтерфейсов, является необработанным типом, который соответствует стиранию его типа в общем объявлении, соответствующем C.

Мне понятно, как это относится к нетипизированному классу - универсальные типы классов заменяются типами стирания. Если родовые классы связаны, то тип стирания соответствует этим границам. Если они не связаны, то тип стирания - Object, например

// unbound class types
public class MyGenericClass<T> {
  public T doSomething(T t) { return t; }
}
MyGenericClass untyped = new MyGenericClass();
Object t = untyped.doSomething("String");

// bound class types
public class MyBoundedGenericClass<T extends Number> {
  public T doSomething(T t) { return t; }
}
MyBoundedGenericClass bounded = new MyBoundedGenericClass();
Object t1 = bounded.doSomething("String"); // does not compile
Number t2 = bounded.doSomething(1); // does compile

Хотя универсальные методы являются методами экземпляра, мне не ясно, что JLS 4.8 применяется к универсальным методам. Тип универсального метода (<K> в более раннем примере) не является нетипизированным, так как его тип определяется параметрами метода - только класс является нетипизированным / необработанным.

Ответы на вопрос(6)

Ваш ответ на вопрос