4

这两种方法在概念上有什么区别吗?

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);    
}

以下 main 方法在没有任何警告的情况下编译,并且在没有任何运行时异常的情况下执行。结果是预期的 - 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在第二种方法中使用。但是有什么陷阱吗?我可能会错过任何区别吗?如果不是,首选哪个版本,为什么?

4

2 回答 2

4

不同之处在于推断的类型Tadd1它是第一个集合的组件类型(Driver),add2它是第二个集合的组件类型(Person)。

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

于 2013-08-12T08:12:22.380 回答
2

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

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

public static <T> void add3(final Collection<? extends T> drivers, final Collection<? super T> persons) {
    persons.addAll(drivers);    
}
于 2013-08-12T08:38:34.867 回答