Java泛型列表中的引用赋值

3

我觉得问这个问题有点儿蠢,但是我还是想问一下。

在下面的代码中,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;
        }
    }
}

我的公司实现了HasId接口,所以我认为应该能够对其进行赋值。为什么不能呢?更重要的是,有没有一种简单的方法将其分配给HasId对象列表。

更新:List ids = (List<HasId>)list; 在无法转换类型时也会出错。


那不是一个类型转换,而是一个引用赋值。类型转换应该像这样:int a = (int) b; - Jeff Storey
@Jeff Storey,我更新了问题。 - Tihom
3个回答

9
这种一般的赋值是被禁止的原因在于可能会进行强制类型转换,然后向ids中添加一个不是MyCompany的东西(比如也实现了HasId接口的MyPerson)。因此,如果允许强制类型转换,那么你就可以这样做。
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。


3

不允许这样做,因为这可能会使您执行以下操作:

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

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


3

它是类型安全的。

List<HasId> ids ;  

声明只接受HasId列表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接