【发布时间】:2010-07-30 10:32:33
【问题描述】:
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 中编写代码,如果 Class2 是子类,我可以确定它自己的泛型类型是 Integer。
查看 java.lang.Class API 以了解适当的方法(它们的名称中有 Generic)。
【讨论】: