java为什么用通配符创建的比较器的compare方法不能接受对象?
在Java中,创建比较器对象是合法的,如下所示:
Comparator<? super Number> comparator = new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
// implementation here
}
};
但您不能将此对象用于这样的简单调用:
Object o1 = new Object(), o2 = new Object();
comparator.compare(o1, o2);
为什么会这样?我认为? super Number
意味着数字及其所有超类
# 1 楼答案
Comparator<? super Number> comparator
意味着comparator
指的是已知的能够接受Number
(或者它是null
)的东西A
Comparator<Object>
可以接受ANumber
;但是编译器不知道aComparator<? super Number>
引用的值是aComparator<Object>
还是aComparator<Number>
。它所知道的是它是可以接受Number
的东西,所以它只允许你通过否:这意味着
Number
是可接受的类型,可以作为参数传递。换句话说,Number
是可接受参数类型的子类型。换句话说,可接受的参数类型是Number
的超类型,因此可以传递Number
见:What is PECS (Producer Extends Consumer Super)?
# 2 楼答案
假设您使用了
? super Double
:您告诉编译器的是,您有一个比较器
Comparator<Double>
,或者Comparator<Number>
,或者Comparator<Object>
,或者Comparator<Serializable>
李>即使您使用
Comparator<Object>
对其进行了初始化,编译器也不知道这一点,因为编译器不执行代码。编译器只知道变量包含上述类型之一的比较器由于变量可能包含一个比较器,该比较器的类型比Object更为特定,因此编译器不会认为传递Object是可以的
# 3 楼答案
o1
和o2
不能用作参数的原因是,它们比Number
更“通用”,因此它们可能指向一个类的实例,该类是从Number
父链的某个点开始的不同层次结构的一部分。类似于,Son
类直接位于Father
的层次结构行中,但不在Grandfather
类的SecondSon
层次结构中。因此,无法传递对Grandfather
类实例的引用,因为它可能指向其SecondSon
层次结构中的实例我试图解释一个类似的观点