2

鉴于此List<Employee>

List <Employee> empList=new ArrayList<Employee>();

当我尝试添加一个Student

l.add(0,new Student(1,2,3));

列表如何解决这个问题并给我编译错误?

4

2 回答 2

5

实际上,它并不是专门进行List检查的,而是编译器(正如您所暗示的那样)。

简单地提供了List两条信息:

  • 有一个E类型List被参数化:

    public interface List<E> extends Collection<E>
    
  • 该方法add接受一个类型的对象E

    boolean add(E e);
    

如果您构建 aList<Employee>然后编译器知道您不能调用add任何东西 并且Employee如果您尝试这样做,则会给出编译器错误。

还应该注意的是,运行时没有这样的检查!因此,如果您设法“偷偷摸摸”通过编译器进行的检查(例如使用原始类型),那么您可以对您做各种错误的事情,List并且运行时不会检测到问题(直到您尝试以非通用方式访问“错误”类型)。

于 2012-08-29T07:22:32.837 回答
0
List<Employee> empList = new ArrayList<Employee>()

在上述情况下,由于您已指定 empList 仅包含Employee.

当您尝试添加任何其他实例类型时,编译器有责任抱怨它不是一个Employee或派生自它。这是因为,您已经为编译器提供了足够的信息,以便它在编译期间决定允许将哪些类型的实例添加到此列表中。因此,编译器知道该add()方法总是期望/或派生自Employeeand not的实例Student。因此,您的情况出现错误。

使用泛型的另一个有趣结果是当您尝试get()从该列表中获取一个元素时。当时的编译器也知道你试图从列表中获取的元素需要是Employee类的。因此,如果您执行非法转换(例如将返回的对象转换get()为 aStudent),编译器会再次抱怨。

以下文章可能有助于理解这个概念:

于 2012-08-29T07:13:38.953 回答