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

杀马特。学长 韩版系。学妹 提交于 2019-12-23 11:14:10

问题


I got a small problem here regarding generics bounded type with lists. Please help out!

Model.java

public class Model {
}

ClassA.java

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

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

It gives me an unchecked cast from Model to T warning on this line:

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

I understand I'm getting this warning because all I can safely cast from a sub class into a super class but not the other way round.

Is there any way to get over this problem or can I just safely supress the warning?


回答1:


You can't do what you're trying to do.

Since T is a subclass of Model:

  • every T is a Model
  • but not every Model is a T.

Specifically:

If you construct a new Model by calling new Model(), the instance is exactly a Model and not an instance of any subclass.

Where Subclass extends Superclass, you can never successfully do this:

(Subclass) new Superclass();

Because of this, you can not successfully cast a new Model to an instance of T.

The compiler will just give you a warning which you can either ignore or suppress, but you'll get a ClassCastException when you run your program and call the add() method.




回答2:


Take this example

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 {
}

The object you've added to models is of runtime type Model, which doesn't have a run() method.

When you eventually try to use the object as an object of type SubModel, you'll get a ClassCastException as I do in the main() method.

You really shouldn't do this, ie. add parent type objects to possible suptype type objects.




回答3:


You need to initialize the list before adding elements in your constructor. I think you you might have copied only the relavant code snippet and thats why it was left out.

Also, I think the only way is to suppress warnings. More info only covariance, contravariance here : Covariance, Invariance and Contravariance explained in plain English?



来源:https://stackoverflow.com/questions/19032215/cast-to-generic-type-t-gives-unchecked-cast-warning

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!