如何学习泛型类的实际类型参数?

时间:2010-08-19 08:44:26

标签: java generics reflection

我有一个参数化类:

class ParameterizedClass<T extends AbstractSomething> {
}

主叫:

new ParameterizedClass<Something>();

那么如何通过使用Java Generics来获取T的实际类型?

4 个答案:

答案 0 :(得分:9)

可以这样做,但type erasure可以使它变得非常困难。正如其他答案所讨论的那样,您要么必须创建ParameterizedClass的子类,要么将T类型的字段添加到ParameterizedClass,并且您需要执行的反射代码是复杂的。< / p>

我建议在这些情况下,解决这个问题:

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完全通用且类型安全,您仍然可以访问类对象。

编辑:解决了评论

答案 1 :(得分:8)

您可以在构造函数中使用此技巧:(请参阅http://www.hibernate.org/328.html

Class<T> parameterType = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

但是我相信这个代码仅在类被子类化并且子类的实例执行它时才有效。

答案 2 :(得分:3)

如果你的意思只是来自对象本身,你就不能。 类型擦除表示信息丢失。

如果你有一个字段,它使用带有具体类型参数的参数化类型, 信息将被保留。

请参阅Angelika Langer's Generics FAQ,尤其是section on type erasure

答案 3 :(得分:0)

这是一个主要有问题的话题,因为它只能在预期的某些条件下工作(特别是在复杂场景中)。

但是Xebia在整个事情上发表了good article