泛型、数组列表与协变

public class Test {
    public static void main(String[] args) {
        ArrayList<XiaoMi> xiaoMiList = new ArrayList<XiaoMi>();

        ArrayList<BYD> bydList = new ArrayList<BYD>();

        run(xiaoMiList); //错误使用
    }
    
    public static void run(ArrayList<Car> list) {
        // 汽车跑的逻辑
        System.out.println("the car runs fast");
    }

}

疑问:xiaoMiList中的每个元素都是Car的子类,为什么不能使用多态的方式实现将ArrayList传给ArrayList呢

java中的协变

在Java中,协变是指一个类型的子类型可以被当作其父类型来使用。例如,如果 XiaoMi 是 Car 的子类,那么 XiaoMi 的对象可以被当作 Car 的对象来使用。这是Java语言设计中的一项重要特性,它支持面向对象编程中的多态性。

数组列表与协变

然而,尽管Java中的基本类型和引用类型支持协变,ArrayList 却不支持协变。这是因为 ArrayList 的设计考虑到了类型安全性和避免潜在的运行时错误。

设计思想

Java中泛型擦除

1. 类型安全性:


Java的设计目标之一是保证类型安全性。如果 ArrayList<XiaoMi> 能够被当作 ArrayList<Car> 使用,那么可能会发生以下情况: 
* 可能意外地向 ArrayList<XiaoMi> 中添加了一个 BYD 对象,因为 BYD 也是 Car 的子类。
* 这种操作在编译时是合法的,但在运行时会导致 ClassCastException,因为 ArrayList<XiaoMi> 实际上只能存储 XiaoMi 对象。

2. 泛型擦除:


Java中的泛型是基于类型擦除实现的。这意味着在编译时类型参数被替换为其实现的原始类型(例如 ArrayList<XiaoMi> 在运行时实际上就是 ArrayList<Object>),而在运行时类型参数的信息被丢弃。
如果 ArrayList<XiaoMi> 能够被当作 ArrayList<Car> 使用,那么编译器无法保证类型安全,因为它不知道 XiaoMi 是否是 Car 的子类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值