Java泛型与通配符误解:两种List泛型参数声明是否等价?
这两个声明完全不等价,咱们一点点拆解来看:
首先先明确原方法的泛型约束:<T extends Comparable<? super T>>,这是Java里定义「可比较类型」的标准写法——它保证了T类型的对象能和自身(以及自身的父类对象)进行比较,比如Integer实现Comparable<Integer>,或者自定义子类继承某个可比较父类,都能满足这个约束。
接下来对比两个List参数的差异:
1. List<? extends T> 的含义
这个声明限定列表元素必须是T的子类(包括T本身)。因为T已经满足T extends Comparable<? super T>,所以这些子类型元素可以安全向上转型为T,用T的比较逻辑处理——这也是max方法能返回T类型结果的基础:列表里的所有元素本质上都能当作T来处理。
2. List<? extends Comparable<? super T>> 的含义
这个声明的范围要宽泛得多:它只要求列表元素是Comparable<? super T>的子类型,但这些元素不一定是T的子类。举个实际例子:
假设T是Integer,那么Comparable<? super Integer>包含Comparable<Integer>、Comparable<Number>、Comparable<Object>这类类型。如果有一个类MyNumber实现了Comparable<Number>,但它并不是Integer的子类,那么List<MyNumber>可以传给List<? extends Comparable<? super Integer>>,但绝对不能传给List<? extends Integer>——因为MyNumber和Integer之间没有继承关系。
3. 核心差异总结
List<? extends T>是List<? extends Comparable<? super T>>的子集:所有符合前者的列表都符合后者,但反过来不成立。- 原方法用
List<? extends T>是为了确保列表元素能安全转型为T,保证max方法能正确返回T类型的最大值;如果换成后者,列表里可能混入非T类型的元素,无法转型为T,直接破坏了方法的返回值约定。
内容的提问来源于stack exchange,提问作者Denis

