为什么 <? extends V> 不适用于 compareByValue 方法?
Why <? extends V> does not work for comparingByValue method?
在JavaJDK中,我注意到Map中有一个静态方法class:
public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K, V>> comparingByValue() {
return (c1, c2) -> c1.getValue().compareTo(c2.getValue());
}
出于好奇,我将代码更改为:
public static <K, V extends Comparable<? extends V>> Comparator<Map.Entry<K, V>> comparingByValue() {
return (c1, c2) -> c1.getValue().compareTo(c2.getValue());
}
编译器在这一行报错:
return (c1, c2) -> c1.getValue().compareTo(c2.getValue());
Error: java: incompatible types: V cannot be converted to capture#1 of ? extends V
让 V 与其子class的对象进行比较可能没有意义,但我很困惑为什么编译器在这种情况下会抛出错误?通配符有界泛型应该是包容性的吧?为什么编译器在 compareTo 方法的参数中期望 V 的 subclass 的对象?
真正需要的是 V
的每个实例都可以与 V
的每个其他实例进行比较(至少就类型系统而言是这样;当然,总是有可能compareTo
实施在 运行 时执行额外要求。
V extends Comparable<? super V>
确保满足该要求:这意味着 V
的实例可与 V
的某些超类型的所有实例相比较,这必然包括 [=] 的所有实例10=]。 (请记住,一个类型的所有实例也是其所有超类型的实例。)
V extends Comparable<? extends V>
,相比之下,不提供任何有用的保证;这意味着 V
的实例可以与 V
的某些子类型的实例进行比较,但该子类型可能根本不相关。
在JavaJDK中,我注意到Map中有一个静态方法class:
public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K, V>> comparingByValue() {
return (c1, c2) -> c1.getValue().compareTo(c2.getValue());
}
出于好奇,我将代码更改为:
public static <K, V extends Comparable<? extends V>> Comparator<Map.Entry<K, V>> comparingByValue() {
return (c1, c2) -> c1.getValue().compareTo(c2.getValue());
}
编译器在这一行报错:
return (c1, c2) -> c1.getValue().compareTo(c2.getValue());
Error: java: incompatible types: V cannot be converted to capture#1 of ? extends V
让 V 与其子class的对象进行比较可能没有意义,但我很困惑为什么编译器在这种情况下会抛出错误?通配符有界泛型应该是包容性的吧?为什么编译器在 compareTo 方法的参数中期望 V 的 subclass 的对象?
真正需要的是 V
的每个实例都可以与 V
的每个其他实例进行比较(至少就类型系统而言是这样;当然,总是有可能compareTo
实施在 运行 时执行额外要求。
V extends Comparable<? super V>
确保满足该要求:这意味着 V
的实例可与 V
的某些超类型的所有实例相比较,这必然包括 [=] 的所有实例10=]。 (请记住,一个类型的所有实例也是其所有超类型的实例。)
V extends Comparable<? extends V>
,相比之下,不提供任何有用的保证;这意味着 V
的实例可以与 V
的某些子类型的实例进行比较,但该子类型可能根本不相关。