public
static
<
T
>
void
sort(List
<
T
>
list, Comparator
<?
super
T
>
c);
public static < T > int binarySearch(List <? extends Comparable <? super T >> list, T key);
public static < T > int binarySearch(List <? extends Comparable <? super T >> list, T key);
extends和super这两个关键字是C#和C++的泛型中都没有的,为什么需要这样的功能呢?
例如如下情形:
class
A { }
class B extends A {}
void addAll(List < A > items) {}
class B extends A {}
void addAll(List < A > items) {}
如下代码:
List
<
A
>
aList
=
;
List < B > bList =
;
addAll(aList); // 可以
addAll(bList); // 编译不通过
![dot.gif](/Images/dot.gif)
List < B > bList =
![dot.gif](/Images/dot.gif)
addAll(aList); // 可以
addAll(bList); // 编译不通过
addAll(bList)是无法编译通过的,这一点在Java、C#、C++中都是如此,怎么办呢?在java中如下处理,修改addAll的接口,改为:
void
addAll(List
<?
extends
A
>
items) {}
这样,addAll(aList)和addAll(bList)都能够编译通过了。
另外super关键在算法中更是好用,如上面介绍的Collections.sort方法。如果你想在C#中实现一个和java.util.Collections.sort一样的方法,你会发现那是做不到的!
为什么C#和C++无法提供这样的功能呢?因为C#和C++都是运行时的泛型支持,bList和aList的类型是不一样的,List<A>和List<B>的实际类型都是不一样的,运行时对泛型的支持目前还无法象处理数组参数那样具备协变能力。而Java的实现是编译器的特性,这样做的缺点就是性能没有得到提升,但是可以提供更好的语法糖。
想起ajoo以前发表的一个观点,就是在应用开发中,泛型提供的关键是类型安全,性能反而是其次。我对此十分认同,重新审视java的泛型,我们会发现其设计颇具创新,而且向后兼容良好!
总结一下我的观点:
Java的泛型,语法有创新,更好用,向后兼容,编写泛型算法更方便,但是没有带来性能提升。
C#泛型,实现有创新,在虚拟机级别支持,运行时支持泛型,性能有提升,但是不好编写泛型算法,不向后兼容。