Можно ли добавить методы по умолчанию в Comparable, не нарушая Java?

Я думал о том, чтобы предложить запрос функции для добавления методов по умолчанию, называемых:

default boolean greaterThan(T o) {
    return compareTo(o) > 0;
}

default boolean smallerThan(T o) {
    return compareTo(o) < 0;
}

default boolean atLeast(T o) {
    return compareTo(o) >= 0;
}

default boolean atMost(T o) {
    return compareTo(o) <= 0;
}

к интерфейсу Comparable, поскольку, на мой взгляд, это сделало бы код более читабельным.

Однако мне интересно, не сломает ли это код. Есть ли такой код, как у Lambda, который сломается, если мы добавим методы по умолчанию?

Если я правильно прочитал это, я бы предположил, что Lambda, по крайней мере, останется работать, пока они не будут пытаться вызывать новые методы, но я не уверен. И я не знаю, могут ли быть какие-либо (очевидные) другие проблемы.

Пожалуйста, не обсуждайте сам возможный запрос функции.


person Maarten Bodewes    schedule 24.01.2021    source источник
comment
Что может случиться: stuartmarks.wordpress. com/2020/09/22/   -  person Johannes Kuhn    schedule 24.01.2021
comment
Может быть полезно: документы. oracle.com/javase/specs/jls/se15/html/   -  person Slaw    schedule 24.01.2021
comment
Спасибо, ребята, прочитал оба. Имеет смысл, что это может вызвать проблемы, но я не считаю их ужасно опасными. Это должен быть довольно странный метод, чтобы вызвать конфликты имен на уровне исходного кода, но да, вы никогда не знаете.   -  person Maarten Bodewes    schedule 24.01.2021
comment
@Slaw, почему бы не сделать это ответом? имхо, вкупе с примером, прямо на него и отвечает.   -  person Eugene    schedule 24.01.2021
comment
@Eugene Не уверен, что понимаю это достаточно хорошо, чтобы дать ответ.   -  person Slaw    schedule 24.01.2021


Ответы (2)


К сожалению, ответ @BasilBourque вводит в заблуждение, хотя он цитирует полезные объекты.

Эта функция никоим образом не будет представлена ​​через субинтерфейс. SortedMap/NavigableMap не применимы: механизма default не было, когда был представлен NavigableMap!

На этом этапе может оказаться целесообразным ввести некоторые или все методы в NavigableMap как методы default в SortedMap с реализациями, которые работают с отсортированными картами и которые в конечном итоге будут автоматически переопределены любыми импликациями Map, которые уже реализовали NavigableMap (поскольку они переопределили все те, что в их реализации).

Однако это означает, что «Эй, посмотрите на NavigableMap, который аналогичен SortedMap точно так же, как вы хотите сделать с Comparable», является вводящим в заблуждение аргументом: ваше предложение включает добавление методов по умолчанию. Этого просто не было на столе тогда.

В конце концов, то, что вы хотите, «почти, но не полностью, обратно совместимо». Архитекторы Oracle/Java Lang часто говорят, что «java не нарушает обратную совместимость», но это грубое упрощение и граничащая ложь. Если вы спросите немного дальше, они в конце концов признают, что это неправда: Суть дела в том, что java взвешивает стоимость любого обратного разрыва (насколько это вероятно и что происходит с кодом, который его сломал? Если он молча все еще компилируется и запускается, но делает что-то не так, это ужасно, если это тривиальное обновление, которое скрипт рефакторинга может автоматически применять каждый раз, это здорово - а затем смешайте шансы, что любая кодовая база наткнется на него, и у вас есть идея «затраты») по сравнению с выгодой от этого.

Затраты здесь очень незначительные. Крайне маловероятно, что какая-либо кодовая база сломается. Однако, если вы действительно хотите предложить эту функцию, было бы очень полезно провести некоторое исследование и попытаться придумать любую библиотеку (или, если вы не можете, посмотрите на 100 лучших списков, о которых пишут в блогах разные люди, анализируя, например, github java-проекты в качестве исходного материала), чтобы просмотреть кучу, чтобы попытаться увидеть, произойдет ли то, что произошло с .isEmpty, с этими методами.

Но есть и плохие новости: маловероятно, что предложение Java-функции будет успешным. С некоторой точки зрения, как автор проекта Lombok, кто-то, кто провел много сотен часов, читая списки рассылки, такие как lambda-dev, который внес большую часть фактического синтаксиса лямбда и концептуальной основы, и провел беседы с несколькими архитекторами языка Java в некоторое время (в основном на конференциях по java) я отправил предложение, которое включало полный патч для самой java и все необходимые обновления, необходимые для JLS, которые вообще не нарушали обратную совместимость, и это никогда не получалось. Даже не так много, как JEP.

В прошлый раз, когда я разговаривал с инженером Oracle, они обещали, что теперь дела обстоят немного лучше, но это не особенно далеко: я не знаю ни одной функции Java поблизости или на горизонте, которая была бы получена от постороннего, который был отправлен прямо в JEP и приблизился к обозримому горизонту возможностей Java за последние 10 лет. Время от времени кто-то (обычно Джо Дарси или Алекс Бакли) запускает проект, чтобы «добавить кучу небольших удобных языковых изменений», например Project Coin (это было 11 лет назад, уф). Второй подход к этому — Project Amber, который, как мне кажется, должен быть более непрерывным. проект против монеты, у которой был определенный короткий промежуток времени.

Маршрут, чтобы получить это в java, по-видимому, будет проходить через янтарь.

person rzwitserloot    schedule 24.01.2021
comment
Опять же, я никогда не говорил, что SortedMap следует применять к каждой реализации Map. Вы исказили мой ответ в совершенно неправильной интерпретации. Пожалуйста, отзовитесь. - person Basil Bourque; 24.01.2021
comment
Ваш ответ по-прежнему в корне вводит в заблуждение, но совсем по другой причине (да, я неправильно понял в первый раз). Ответ был отредактирован, чтобы отразить это. - person rzwitserloot; 24.01.2021
comment
Честно говоря, я не думаю, что ответы следует использовать для атаки на другие ответы; если вы считаете, что что-то можно улучшить, вы можете использовать раздел комментариев (и я думаю, вы уже это сделали). Кроме того, вы уже указали, что были неправы в отношении первоначальной атаки, но текст, кажется, все еще включает это. - person Maarten Bodewes; 26.01.2021
comment
@MAartenBodewes нет, текст был обновлен, и в аргументе используются рассуждения и фальсифицируемая информация, чтобы доказать свою правоту. Трактовать это как нападение на человека - это у вас в голове, а не в этом ответе. Ни в коем случае это не посягает на авторитет или характер Бэзила Бурка. Это просто уничтожает его аргумент (используя фальсифицируемые факты). Не выдумывайте личное пренебрежение там, где его нет. - person rzwitserloot; 26.01.2021

Как прокомментировал Йоханнес Кун, Стюарт Маркс задокументирован случай, когда добавление CharSequence.isEmpty() метод по умолчанию для Java 15 сломал стороннюю библиотеку.

Итак, учитывая историческую приоритетность новых версий Java, максимально обратно совместимых с существующими приложениями, лучший подход - определить новый интерфейс. Новый интерфейс представит ваши новые методы. Теоретически старый интерфейс может в конце концов, по прошествии очень долгого времени, быть помечен как устаревший, чтобы предложить постепенно заменить старый интерфейс новым. Тем временем существующий код не будет нарушен, в то время как новый код сможет использовать преимущества новых идей.

Это было сделано, например, в Map. Подинтерфейс SortedMap появился с Java 1.2 (также известной как Java 2). Спустя годы, в Java 6, появилась идея расширить этот интерфейс дополнительными методами. Но пересмотр SortedMap сопряжен с риском нарушения существующих реализаций в связанных библиотеках Java, а также нарушения сторонних реализаций. Поэтому вместо этого они решили определить новый интерфейс NavigableMap. Они сделали новый интерфейс NavigableMap подинтерфейсом SortedMap.

NavigableMap на самом деле просто "2.0" версия SortedMap. Насколько мне известно, нет никаких причин, по которым любая реализация не хотела бы поддерживать более широкий набор методов, а не тот, который есть в SortedMap. Так что, конечно, было бы неплохо иметь только один такой интерфейс, а не два, но c’est la vie.

Вот графическая таблица, которую я сделал, показывающую различные реализации интерфейса Map в комплекте с Java 11. Вы можете видеть, как интерфейсы SortedMap и NavigableMap живут бок о бок.

Таблица реализаций карт в Java 11, сравнение их возможностей

Я полностью поддерживаю вашу идею эффективного расширения Comparable с помощью этих конкретных методов (кстати, хорошее название тоже). Но я считаю, что ваше предложение будет работать только как новый подинтерфейс Comparable.

person Basil Bourque    schedule 24.01.2021
comment
Спасибо, наверное, должно было быть lessThan, если честно. Теперь имя для нового Comparable... - person Maarten Bodewes; 24.01.2021
comment
Однако часть этого ответа о SortedMap совершенно неверна. Любой существующий компаратор может бесплатно получить метод atMost. Это, действительно, метод по умолчанию. В отличие от SortedMap: не все карты отсортированы; такие методы, как 'headMap', не могут быть (разумно) написаны по умолчанию, чтобы они работали для всех существующих интерфейсов карты. Задача, которую выполняет headMap, принципиально неэффективна, например. HashMap, наиболее часто используемая реализация карты. - person rzwitserloot; 24.01.2021
comment
Методы по умолчанию не были доступны в Java 6, что очень важно. - person chrylis -cautiouslyoptimistic-; 24.01.2021
comment
@rzwitserloot Я никогда не говорил о применении SortedMap ко всем реализациям Map. Мой ответ касается отношений между SortedMap и NavigableMap. Пожалуйста, покажите мне, где я обсуждал применение ко всем реализациям Map, чтобы я мог исправить эту часть. - person Basil Bourque; 24.01.2021
comment
Да, это печально. Я неправильно прочитал ваш комментарий, но теперь есть другая фундаментальная проблема с вашим ответом: NavigableMap был создан, когда методов default не существовало, и это делает проблему SortedMap/NavigableMap почти полностью не относящейся к этому вопросу. Этот ответ по-прежнему вводит в заблуждение и делает неверный вывод, даже если он начинается со ссылок на полезные ресурсы. - person rzwitserloot; 24.01.2021
comment
Хотя то, что касается методов по умолчанию, может быть правдой, я думаю, что расширение интерфейса все равно может привести к конфликтам, методу по умолчанию или не методу по умолчанию. Так что введение в заблуждение заходит слишком далеко, если вы спросите меня. - person Maarten Bodewes; 26.01.2021