Java 泛型,获取泛型参数的类<T>

2022-08-31 22:12:02

我有一个抽象类:

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

我需要填满孩子 - 每个孩子都有自己的孩子ClassT clazz;RootProcessorT

我只找到了一个解决方案,但它需要编译器参数-Xlint:unchecked

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

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


答案 1

类型安全,但样板的方法是传递令牌“编译器可以看到它的位置”: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

有一个相同主题的帖子:反映泛型

以及一个实现它的类:TypeArgumentsUtils.java

单元测试中就是一个示例。

因此,如果您有此类:

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

比你会得到第一个参数:

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

推荐