Почему не работает для сравнения метод ByValue? - PullRequest
0 голосов
/ 22 января 2020

В Java JDK я заметил, что в классе Map есть метод stati c:

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 нельзя преобразовать в захват # 1 из? extends V

Возможно, не имеет смысла сравнивать V с объектом его подкласса, но я запутался, почему компилятор выдает ошибку в этом случае? Обобщенные ограниченные шаблоны должны быть включительно, не так ли? Почему компилятор ожидает объект подкласса V в параметре метода compareTo?

1 Ответ

2 голосов
/ 22 января 2020

Все, что действительно требуется, - это чтобы каждый экземпляр V был сопоставим с любым другим экземпляром V (по крайней мере, насколько позволяет система типов; конечно, всегда возможно, что реализация compareTo обеспечивает дополнительные требования во время выполнения).

V extends Comparable<? super V> обеспечивает выполнение этого требования: это означает, что экземпляры V сопоставимы со всеми экземплярами некоторого супертипа V, который обязательно включает все экземпляры V. (Имейте в виду, что все экземпляры типа также являются экземплярами всех его супертипов.)

V extends Comparable<? extends V>, напротив, не дает никакой полезной гарантии; это означает, что экземпляры V можно сравнить с экземплярами некоторого подтипа V, но этот подтип может вообще не иметь отношения.

...