2013-08-12 35 views
4

这两种方法有什么概念上的区别吗?Java泛型 - 扩展和超级用法的特例

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第二种方法。但是有什么问题吗?我可能错过的任何区别?如果不是,哪一个版本是首选的,为什么?

回答

4

所不同的是在被推断T类型:在add1它是第一集合(Driver)的分量类型,在add2它的第二集合(Person)的组件类型。

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

2

如果A是B的超类型,那么B扩展A,所以两个版本之间没有区别。

注意,你也可以同时使用superextends

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