почему переменная type невосстанавливается в java
В настоящее время я изучаю java generics, а ниже приведен список типов в Java, которые не поддаются восстановлению.
Тип не может быть повторно идентифицирован, если он является одним из следующих:
• переменная типа (такая как T
)
• Параметрированный тип с фактическими параметрами (такими как List<Number>, ArrayList<String>, or Map<String, Integer>
)
• Параметрированный тип с привязкой (например, List<? extends Number> or Comparable<? super String>
)
Я понимаю, почему параметризованный тип с фактическим параметром и параметризованным типом с привязкой является недопустимым, потому что после стирания во время работы единственная информация о типе слева - это List
, но почему переменная типа (например, T
) является невосстанавливаемым типом? Я думал, что во время выполнения, после стирания типа, T
станет Object
(если T
является параметром несвязанного типа), поэтому информация типа доступна.
Что-то не так с моим пониманием?
Ответы
Ответ 1
Объект можно повторно использовать, когда его информация о наборе текста не теряется во время компиляции. Некоторые операции не допускаются на невосстанавливаемые объекты. Например, мы не можем сделать экземпляр.
Родовые типы не поддаются восстановлению, и поэтому мы не можем
List <Conference> instance
Это было бы практично в некоторых случаях, но мы не должны забывать, что JDK должен быть обратно совместимым с одной версии на другую. Это ограничение объясняет некоторые ограничения в реализациях.
Тип Java можно повторно идентифицировать, если он полностью отображается во время выполнения (без стирания типа):
primitive type
non-parametric type
parametric type in which all arguments of type are unbounded jokers (List <?>)
type "raw" (List)
table whose type of elements is reifiable
Я не знаю, поможет ли это вам, я могу удалить его, если нет, хорошо провести день!
Ответ 2
В документах указано, что
Невосстанавливаемый тип не имеет всей информации, доступной во время выполнения.
Тип T
во время выполнения - Object
поэтому информация теряется. Примером потерянной информации является способ создания объекта. Рассмотрим этот класс:
public class A {
private int a;
public A() {
a = 5;
}
}
Теперь посмотрим на этот не компилируемый код:
public class Generic<T> {
T foo() {
return new T(); //Compiler Error!
}
}
Если это разрешено, и вы создаете Generic<A> g = new Generic<>();
и вызывая g.foo()
, конструктор T
не может быть вызван, потому что во время выполнения T
известен только как Object
. Следовательно, действительный экземпляр A
не может быть создан и возвращен. Вы даже не можете быть уверены в том, какая информация требуется конструктору T
Информация о том, как можно построить T
теряется.
Это одна из причин, почему параметры типа должны быть невосстанавливаемыми типами.