Java泛型,获取Class 通用参数

问题描述 投票:39回答:2

我有一个抽象类:

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我们可以这样做吗?

java generics
2个回答
32
投票

类型安全但是样板的方法是传递Class<T>标记“编译器可以看到它”:

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);
    }
}

如果你正在做一个未经检查的演员,但你“知道你在做什么”并希望编译器停止抱怨,那么正确的方法是将非类型安全但你知道的工作位置和使用@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)


2
投票

有一个相同主题的帖子:Reflecting generics

还有一个实现它的类:TypeArgumentsUtils.java

一个例子是单元测试。

所以如果你有这个课:

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

比你得到第一个参数:

Class barClass = TypeArgumentsUtils.getFirstTypeArgument(
        RootProcessor.class, BarProcessor.class);
© www.soinside.com 2019 - 2024. All rights reserved.