【问题标题】:Why <? extends V> does not work for comparingByValue method?为什么<?扩展 V> 不适用于 compareByValue 方法?
【发布时间】:2020-05-08 05:02:17
【问题描述】:

在Java JDK中,我注意到Map类中有一个静态方法:

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());

错误:java:不兼容的类型:V 无法转换为 capture#1 of ?扩展V

将 V 与其子类的对象进行比较可能没有意义,但我很困惑为什么编译器会在这种情况下抛出错误?通配符有界泛型应该是包容性的吧?为什么编译器在 compareTo 方法的参数中期望 V 子类的对象?

【问题讨论】:

  • &lt;? super V&gt;&lt;? extends V&gt; 表示不同的东西——看看here
  • 为了了解superextend 之间的理解,我使用了我创建的以下大脑技巧:put/write 事情总是比 read from,super 表示 superman 表示他可以写,所以当你需要添加一些东西时使用&lt;? super V&gt;,左边是&lt;? extend V&gt;,它只是让你只读。 **这是我使用的脑图,何时使用extend vs super **

标签: java generics bounded-wildcard


【解决方案1】:

真正需要的是V 的每个实例都与V 的每个其他实例相当(至少就类型系统而言;当然,compareTo 实现总是有可能强制执行运行时的附加要求)。

V extends Comparable&lt;? super V&gt; 确保满足该要求:这意味着V 的实例与V 的某些超类型的所有实例相当,这必然包括V 的所有实例。 (请记住,一个类型的所有实例也是其所有超类型的实例。)

相比之下,V extends Comparable&lt;? extends V&gt; 不提供任何有用的保证;这意味着V 的实例可以与V 的某些子类型的实例进行比较,但该子类型可能根本不相关。

【讨论】:

    猜你喜欢
    • 2022-01-10
    • 1970-01-01
    • 2011-03-21
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 2019-04-23
    • 2015-12-17
    • 2019-09-23
    相关资源
    最近更新 更多