guice的TypeLiteral如何工作?
Guice的TypeLiteral如何克服Javagenerics类型擦除过程?
它创造了奇迹,但这是如何实现的?
这里使用的技巧是generics超类型的签名存储在子类中,因此可以在擦除时存活 。
如果你创建一个匿名子类new TypeLiteral
Guice可以在其上调用>() {}
getClass().getGenericSuperclass()
并得到一个java.lang.reflect.ParameterizedType
,其上存在一个方法getActualTypeArguments()
来获取List
列为ParameterizedType
的实例。
通过匿名类型的组合,子类化以及Java不会完全擦除所有generics声明的事实。
如果仔细观察,TypeLiteral会有一个受保护的构造函数,因此在构造一个创建TypeLiteral的匿名子类的新构造函数时会使用额外的{}。
在Java中,generics声明保留在Class和Method声明中,所以如果我写这个。
public abstract class Class1 { } public class Class2 extends Class1 { }
我实际上可以在Class1中编写代码,如果Class2是子类,它可以判断出它自己的generics类型是Integer。
查看java.lang.Class API以获取相应的方法(名称中包含Generic)。