【发布时间】:2010-08-19 08:44:26
【问题描述】:
我有一个参数化类:
class ParameterizedClass<T extends AbstractSomething> {
}
调用:
new ParameterizedClass<Something>();
那么如何使用 Java 泛型获得 T 的实际类型?
【问题讨论】:
标签: java generics reflection
我有一个参数化类:
class ParameterizedClass<T extends AbstractSomething> {
}
调用:
new ParameterizedClass<Something>();
那么如何使用 Java 泛型获得 T 的实际类型?
【问题讨论】:
标签: java generics reflection
可以做到,但type erasure 会让它变得非常困难。正如其他答案所讨论的那样,您要么必须创建ParameterizedClass 的子类,要么将T 类型的字段添加到ParameterizedClass,并且您需要执行此操作的反射代码很复杂。
在这些情况下,我的建议是解决这样的问题:
class ParameterizedClass<T> {
private Class<T> type;
/** Factory method */
public static <T> ParameterizedClass<T> of(Class<T> type) {
return new ParameterizedClass<T>(type);
}
/** Private constructor; use the factory method instead */
private ParameterizedClass(Class<T> type) {
this.type = type;
}
// Do something useful with type
}
由于 Java 对静态方法的类型推断,您可以在没有太多额外样板的情况下构建您的类:
ParameterizedClass<Something> foo = ParameterizedClass.of(Something.class);
这样,您的ParameterizedClass 是完全通用且类型安全的,您仍然可以访问类对象。
编辑:解决评论
【讨论】:
你可以在你的构造函数中使用这个技巧:(见http://www.hibernate.org/328.html)
Class<T> parameterType = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
但我相信这段代码只有在类被子类化并且子类的实例执行它时才有效。
【讨论】:
如果你的意思只是从对象本身,你不能。 类型擦除意味着信息丢失。
如果你有一个 field 使用带有具体类型参数的参数化类型,那个信息会被保留。
请参阅Angelika Langer's Generics FAQ,尤其是section on type erasure。
【讨论】:
这是一个最有问题的话题,因为它只在预期的特定条件下有效(特别是在复杂场景中)。
但 Xebia 发布了一个 good article 整件事。
【讨论】: