带有通用列表的Java引用分配

时间:2010-10-15 18:03:39

标签: java generics list casting

我觉得这很愚蠢,但我是。

List<HasId> ids = list在以下代码中给出了编译错误:

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实现了HasId所以我认为我应该可以分配它。为什么我不能?并且更重要的是,将此分配给HasId对象列表的简单方法是什么。

更新:列表ids = (List<HasId>)list;也打破了不可转换的类型

3 个答案:

答案 0 :(得分:9)

不允许这样的通用赋值的原因是可以进行转换,然后向ids添加一些不是MyCompany的东西(也许MyPerson也实现了HasId)。因此,如果演员被允许,那么你可以这样做。

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

现在该列表打破了通用保证,因为您的列表已声明为<MyCompany>,其中包含MyPerson。

你可以像这样投射它。

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

但是不允许使用add()操作,但如果愿意,可以迭代它以获取id。

答案 1 :(得分:3)

这是不允许的,因为它可能允许你这样做:

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

您可能会发现使用List<? extends HasId>

会更好

答案 2 :(得分:3)

typesafety

List<HasId> ids ;  

声明只接受HasId的列表。