繁体   English   中英

转换为泛型类型(T)会发出“未经检查的强制转换”警告

[英]Cast to generic type (T) gives “unchecked cast” warning

关于带有列表的泛型有界类型,我遇到了一个小问题。 请帮忙!

Model.java

public class Model {
}

ClassA.java

public class ClassA<T extends Model> {
    private List<T> models;

    public ClassA() {
        models.add((T) new Model());
    }
}

它在这一行给我一个从模型到T警告的未经检查的强制转换:

models.add((T) new Model());

我知道我收到了这个警告,因为我可以安全地从一个子类投射到一个超级类而不是反过来。

有没有办法解决这个问题,还是我可以安全地抑制警告?

你不能做你想做的事。

由于TModel的子类:

  • 每个T都是一个模型
  • 但不是每个模型都是T。

如果通过调用new Model()来构造新模型,则实例恰好是Model而不是任何子类的实例。

Subclass扩展Superclass的地方 ,你永远不能成功地做到这一点:

(Subclass) new Superclass();

因此,您无法成功将新模型强制转换为T的实例。

编译器只会给你一个警告,你可以忽略或抑制,但是当你运行你的程序并调用add()方法时你会得到一个ClassCastException

举个例子

public static void main(String[] args) {
    ClassA<SubModel> models = new ClassA<>();
    for (SubModel model : models.getModels()){
        model.run(); // runtime ClassCastException
    }
}
public static class ClassA<T extends Model> {
    private List<T> models = new LinkedList<>();

    public ClassA() {
        models.add((T)new Model()); // compiles and warns
    }

    public List<T> getModels() {
        return models;
    }
}
public static class SubModel extends Model {
    public void run() {
        System.out.println(this);
    }
}
public static class Model {
}

您添加到models的对象是运行时类型Model ,它没有run()方法。

当您最终尝试将对象用作SubModel类型的对象时,您将像在main()方法中那样获得ClassCastException

你真的不应该这样做,即。 将父类型对象添加到可能的suptype类型对象。

在构造函数中添加元素之前,需要初始化列表。 我想你可能只复制了相关的代码片段,这就是为什么它被遗漏了。

此外,我认为唯一的方法是抑制警告。 更多信息只有协方差,逆变在这里: 协方差,不变性和逆变性用简单的英语解释?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM