Как Guice TypeLiteral преодолевает процедуру стирания универсальных типов Java?
Это творит чудеса, но как это достигается?
Как Guice TypeLiteral преодолевает процедуру стирания универсальных типов Java?
Это творит чудеса, но как это достигается?
Хитрость, которая используется здесь, заключается в том, что сигнатуры универсальных супертипов хранятся в подклассах и, таким образом, выживают при стирании.
Если вы создаете анонимный подкласс new TypeLiteral<List<String>>() {}
, Guice может вызывать getClass().getGenericSuperclass()
и получите java.lang.reflect.ParameterizedType
, для которого существует метод getActualTypeArguments()
, чтобы получить List<String>
как экземпляр ParameterizedType
.
Благодаря сочетанию анонимных типов, подклассов и тому факту, что Java не полностью стирает ВСЕ универсальные объявления.
Если вы внимательно посмотрите, у TypeLiteral есть защищенный конструктор, поэтому вы используете дополнительный {} при создании нового, который создает анонимный подкласс TypeLiteral.
В Java общие объявления сохраняются в объявлениях классов и методов, поэтому, если я напишу это.
public abstract class Class1<T>
{
}
public class Class2 extends Class1<Integer>
{
}
На самом деле я могу написать код в Class1, который может определить, что его собственный общий тип — Integer, если Class2 был подклассом.
Проверьте API java.lang.Class для соответствующих методов (в их названии есть Generic).