Java泛型 - 扩展和超级使用的特例

时间:2013-08-12 08:06:42

标签: java generics extends super

这两种方法之间是否有任何概念上的区别?

public static <T> void add1(final Collection<T> drivers, final Collection<? super T> persons) {
    persons.addAll(drivers);    
}

public static <T> void add2(final Collection<? extends T> drivers, final Collection<T> persons) {
    persons.addAll(drivers);    
}

以下主方法在没有任何警告的情况下编译,并在没有任何运行时异常的情况下执行。结果是预期的一个--4。

public static void main(String[] args) {
    final Person person1 = new Person();
    final Person person2 = new Person();
    final Collection<Person> persons = new ArrayList<>();
    persons.add(person1);
    persons.add(person2);

    final Driver driver1 = new Driver();
    final Collection<Driver> drivers = new ArrayList<>();
    drivers.add(driver1);

    add1(drivers, persons);
    add2(drivers, persons);

    System.out.println(persons.size());
}

我知道PECS原则,并且由于第一种方法中的persons是消费者,因此应分别使用super - extends应该用于drivers在第二种方法中。但是有没有陷阱?我可能会错过任何差异?如果没有,哪个版本是首选,为什么?

2 个答案:

答案 0 :(得分:4)

区别在于推断T的类型:在add1中,它是第一个集合(Driver)的组件类型,在add2中它是第二个集合的组件类型(Person)。

在这种情况下,T未在方法体中使用,因此没有明显的区别。

答案 1 :(得分:2)

如果A是B的超类型,则B扩展A,因此两个版本之间没有区别。

请注意,您还可以同时使用superextends

public static <T> void add3(final Collection<? extends T> drivers, final Collection<? super T> persons) {
    persons.addAll(drivers);    
}