Java 转换为泛型类型(T)时给出;“未经检查的铸件”;警告

Java 转换为泛型类型(T)时给出;“未经检查的铸件”;警告,java,list,generics,bounded-types,Java,List,Generics,Bounded Types,我在这里遇到了一个关于泛型的小问题,有界类型和列表。请帮帮我 Model.java public class Model { } ClassA.java public class ClassA<T extends Model> { private List<T> models; public ClassA() { models.add((T) new Model()); } } 我知道我得到这个警告是因为我能安全地从一个子类转

我在这里遇到了一个关于泛型的小问题,有界类型和列表。请帮帮我

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是模型的一个子类:

  • 每个T都是一个模型
  • 但不是每个模型都是T。
    • 具体而言:

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

      在子类扩展超类的情况下,您永远无法成功做到这一点:

      (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 {
      }
      
      publicstaticvoidmain(字符串[]args){
      ClassA模型=新ClassA();
      对于(子模型:models.getModels()){
      model.run();//运行时ClassCastException
      }
      }
      公共静态类A{
      私有列表模型=新的LinkedList();
      公共甲级(){
      models.add((T)new Model());//编译并发出警告
      }
      公共列表getModels(){
      收益模型;
      }
      }
      公共静态类子模型扩展模型{
      公开募捐{
      System.out.println(本文件);
      }
      }
      公共静态类模型{
      }
      
      添加到
      models
      的对象属于运行时类型
      Model
      ,没有
      run()
      方法

      当您最终尝试将该对象用作
      子模型类型的对象时,您将得到一个
      ClassCastException
      ,就像我在
      main()
      方法中所做的那样


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

      t可以是模型的子类。所以不能将模型强制转换为其子类。你想做什么?为什么不
      models.add(newt())?请注意,即使您可以强制转换并添加它,当您尝试将列表中的元素用作
      T
      类型对象时,您也会得到一个
      ClassCastException
      ,其中
      T
      Model
      的子类@Cruncher
      new T()
      由于类型擦除而无法编译。您正在尝试反向执行此操作。忽视这个警告是不安全的。想象一下扩展模型的类B。然后声明ClassA(这是有效的,因为B扩展了模型)。然后尝试从新模型到B进行案例分析。这将失败,因为B是模型,而a模型不是B。抑制警告只会延迟不可避免的
      ClassCastException
      。诚然,列表需要进行
      新建
      ed,但这与
      (T)
      演员阵容无关。
      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 {
      }