Java泛型,获取泛型参数</t>的Class <t>

时间:2013-05-28 18:40:22

标签: java generics

我有一个抽象类:

public abstract class RootProcessor<T> {
    Class<T> clazz;
}

我需要在ClassT clazz;的孩子身上填写RootProcessor - 每个孩子都有自己的T

我发现只有一个解决方案,但它需要编译器参数-Xlint:unchecked

public RootProcessor(){
    this.clazz = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}

这是最好的解决方案吗?我们可以在没有-Xlint:unchecked的情况下做同样的事吗吗?

2 个答案:

答案 0 :(得分:32)

执行此操作的类型安全但是样板式方法是传递Class<T>令牌&#34;编译器可以在其中看到&#34;:

public abstract class RootProcessor<T> {
    Class<T> clazz;

    protected RootProcessor<T>(Class<T> clazz) {
        this.clazz = clazz;
    }
}

public class FooProcessor extends RootProcessor<Foo> {
    public FooProcessor() {
        super(Foo.class);
    }
}

如果您正在进行未经检查的演员,但您已经知道自己在做什么&#34;并希望编译器停止抱怨,正确的方法是使用@SuppressWarnings本地化非类型安全但你知道它们的工作位:

public abstract class RootProcessor<T> {
    Class<T> clazz;
    { initClazz(); }

    @SuppressWarnings("unchecked")
    private void initClazz() {
        // the usual verbiage you already have in your question
        this.clazz = this.getClass().getGenericSuperclass().yadda().blah();
    }
}

(我不会反对你:P)

答案 1 :(得分:2)

有相同主题的帖子:Reflecting generics

实现它的类:TypeArgumentsUtils.java

一个例子是单元测试。

所以如果你有这个课程:

public class BarProcessor extends RootProcessor<Bar> {
    public BarProcessor() {
    }
}

比得到第一个参数:

Class barClass = TypeArgumentsUtils.getFirstTypeArgument(
        RootProcessor.class, BarProcessor.class);