鉴于此List<Employee>
:
List <Employee> empList=new ArrayList<Employee>();
当我尝试添加一个Student
:
l.add(0,new Student(1,2,3));
列表如何解决这个问题并给我编译错误?
实际上,它并不是专门进行List
检查的,而是编译器(正如您所暗示的那样)。
简单地提供了List
两条信息:
有一个E
类型List
被参数化:
public interface List<E> extends Collection<E>
该方法add
接受一个类型的对象E
:
boolean add(E e);
如果您构建 aList<Employee>
然后编译器知道您不能调用add
任何东西, 并且Employee
如果您尝试这样做,则会给出编译器错误。
还应该注意的是,运行时没有这样的检查!因此,如果您设法“偷偷摸摸”通过编译器进行的检查(例如使用原始类型),那么您可以对您做各种错误的事情,List
并且运行时不会检测到问题(直到您尝试以非通用方式访问“错误”类型)。
List<Employee> empList = new ArrayList<Employee>()
在上述情况下,由于您已指定 empList 仅包含Employee
.
当您尝试添加任何其他实例类型时,编译器有责任抱怨它不是一个Employee
或派生自它。这是因为,您已经为编译器提供了足够的信息,以便它在编译期间决定允许将哪些类型的实例添加到此列表中。因此,编译器知道该add()
方法总是期望/或派生自Employee
and not的实例Student
。因此,您的情况出现错误。
使用泛型的另一个有趣结果是当您尝试get()
从该列表中获取一个元素时。当时的编译器也知道你试图从列表中获取的元素需要是Employee
类的。因此,如果您执行非法转换(例如将返回的对象转换get()
为 aStudent
),编译器会再次抱怨。
以下文章可能有助于理解这个概念:
Generics