为什么多态不适用于泛型?

时间:2016-01-20 08:46:32

标签: java generics

以下代码有什么问题

import java.util.*;

public class Test {
    static class Car {}
    static class bmw extends Car{}

    List<Car> list = new LinkedList<bmw>();
}

Complier显示以下错误:

Test.java:7: error: incompatible types: LinkedList<bmw> cannot be converted to List<Car>
    List<Car> list = new LinkedList<bmw>();
                     ^

为什么它不起作用?

3 个答案:

答案 0 :(得分:2)

当你写

时适用
List<? extends Car> list = new LinkedList<bmw>();

当您声明List<Car> list时,您可以将任何汽车放入生成的list(不只是bmw)中。因此,List<Car>不是List<bmw>,因为它允许执行与List<bmw>不兼容的操作。假设你有

List<Bmw> bmwList = new LinkedList<Bmw>();
List<Car> carList = bmwList; // let's assume this works as you want
carList.add(new Audi()); // works normally: you can put Audi into the list of cars
    // so our bmwList becomes broken here
Bmw bmw = bmwList.get(0); // this should work as we have list of BMW, 
    // but we suddenly got an Audi!

答案 1 :(得分:0)

创建List Car意味着它将保存Car的所有实例,

  • Your bmw is a Car
  • 但您的Car is not bmw

    因此,如果您想轻松地在bmw列表中插入Car,但如果您想要插入所有类extending Car,那么您可以使用Tagir提到的方法。

答案 2 :(得分:0)

作为Tagir答案的补充:JVM在运行时执行一个名为“Type Erasure”的过程。

这意味着;你的原始清单

List<Car> list = new LinkedList<bmw>();

变为

List list = new LinkedList();

在运行时。为了在运行时保持类型安全性,编译器在使用泛型时采取预防措施并执行静态类型检查。