JAVA List泛型限制

相信有很多朋友已经发现在JAVA中下面的代码会报错,但却不知道为什么,百度搜来搜去也都没有一个完全能够让人信服的解释。

public class Tester{
    public static void main(String[] args) {
        List<? extends Chinese> list = new ArrayList<ZhangSan>();
//      Error
//      list.add(new ZhangSan());
    }
}

public class Human{}

public class Chinese extends Human{}

public class ZhangSan extends Chinese{}

public class LiSi extends Chinese{}

其实原因并不复杂。

首先我们要理解List<? extends Chinese>的含义,以及它和List<Chinese>的异同。

它们的相同之处在于都代表一个可以存放Person及其子类的List。

它们的不同之处在于List<? extends Chinese> list = new ArrayList<ZhangSan>()是可以编译通过的,而List<Chinese> list = new ArrayList<ZhangSan>()是无法通过编译的(至于为什么,网上有很多解说,比如 Java 泛型 <? super T> 中 super 怎么 理解?与 extends 有何不同?)。

 

好像说了个废话。

 

关键点来了,注意List<? extends Chinese> list只是声明,而new ArrayList<ZhangSan>()才是真正的具体的实现,Chinese类很可能不止一个子类,比如上例中除了ZhangSan还有LiSi,如果编译器不禁止add方法,那么很可能你会这么做:

List<? extends Chinese> list = new ArrayList<ZhangSan>();
list.add(new LiSi());

注意注意注意!!!你往ArrayList<ZhangSan>()里面放了个LiSi!!!如果编译器允许你这么做,会导致什么后果呢?

如果你真的想要一个既能放ZhangSan又能放LiSi的List,那正确的做法应该是

List<Chinese> list = new ArrayList<>();

同理,为什么下面代码反而能正常运行(看声明好像是只能放Chinese的祖宗,但事实上只能放Chinese的子孙),大家应该就能理解了吧。

List<? super Chinese> list = new ArrayList<Human>();
        list.add(new LiSi());
        list.add(new Chinese());
//      Error
//      list.add(new Human());

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值