【问题标题】:Java generics, get Class<T> of generic parameterJava泛型,获取泛型参数的Class<T>
【发布时间】:2013-05-28 18:40:21
【问题描述】:

我有一个抽象类:

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

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

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

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

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

【问题讨论】:

  • 不要使用-Xlint:unchecked,如果您需要不安全的演员表,请尽可能在本地使用@SuppressWarnings
  • 而且,是的,如果编译器无法从头到尾跟踪 T 的类型,则无法在运行时安全地获取 Class&lt;T&gt;。这里的类型安全但样板化的方法是简单地引入一个受保护的构造函数,该构造函数将clazz 作为参数。
  • @millimoose:你为什么不把它写成答案呢?我几乎没有什么可以添加到您的 cmets ;-)
  • 是的,这是一个很好的答案。我认为带参数的构造函数是一个很好的解决方案。这个问题的简单答案)))
  • 例如:key = gson.fromJson(json, key.getClass().getGenericSuperclass());修复key = gson.fromJson(json,HashMap.class);

标签: java generics


【解决方案1】:

执行此操作的类型安全但样板化的方法是传递Class&lt;T&gt; 标记“编译器可以看到的地方”:

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

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 2016-03-31
    相关资源
    最近更新 更多