Java Reference assignment with generic lists

夙愿已清 提交于 2019-12-12 15:00:09

问题


I feel stupid asking this but I am.

The line List<HasId> ids = list is giving a compile error in the following code:

public class MyGarbageClass {

    public void myMethod(List<MyCompany> list){
        List<HasId> ids = list;
    }

    interface HasId {
        int getId();
    }
    class MyCompany implements HasId{
        private int id = 5;
        @Override
        public int getId() {
            return id;
        }
    }
}

MyCompany implements HasId so I thought I should be able to assign it. Why cant I? And more importantly, what is an easy way to assign this to HasId list of objects.

update: List ids = (List<HasId>)list; breaks also on inconvertible types


回答1:


The reason why generic assignment like this is disallowed is it possible to do the cast and then add something to ids which is not a MyCompany (perhaps MyPerson which also implements HasId). So if the cast was allowed then you could do this.

public void myMethod(List<MyCompany> list){
    List<HasId> ids = list;
    ids.add(new MyPerson());
}

Now the list has broken the generic guarantee because you have list that was declared as <MyCompany> with a MyPerson in it.

You could cast it like this.

public void myMethod(List<MyCompany> list){
    List<? extends HasId> ids = list;
}

But add() operations will not be permitted, but you can iterate it to get the id if you wish.




回答2:


It's not allowed because it might allow you to do this:

List<MyCompany> companies = ...;
List<HasId> ids = companies;
ids.add(new HasId() {});
MyCompany c = companies.pop(); // <---- Not a MyCompany!!!!

You might find it better to use List<? extends HasId>




回答3:


It is typesafety.

List<HasId> ids ;  

It is declared to accept only list of HasId.



来源:https://stackoverflow.com/questions/3944826/java-reference-assignment-with-generic-lists

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