Почему в записях Java есть методы доступа вместо общедоступных полей final? [закрыто]

JEP-395 говорит

класс записи автоматически получает множество стандартных членов:

  • Для каждого компонента в заголовке два члена: открытый метод доступа с тем же именем и возвращаемым типом, что и компонент, и закрытое конечное поле с тем же типом, что и компонент;

Если сгенерированное конечное поле имеет то же имя, что и метод доступа, почему вместо этого не создается общедоступное конечное поле?

4 ответа

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

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

Процитируем пример, приведенный Holger в комментариях:

классы и предоставлять один и тот же API независимо от их внутреннего представления.

Короче говоря, создание аксессуаров для полей предлагает большую гибкость и возможности, чем прямой доступ к полю. То же самое относится и к простым неизменяемым классам.

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

      public record MyRecord(String myProperty) {
    @Override
    public String myProperty() {
        return "The property is " + myProperty;
    }
}

Что-то подобное было бы невозможно с общедоступными конечными полями.

Обычно рекомендуется использовать методы доступа вместо прямого доступа к полю. Даже с записями имеет смысл продолжить эту практику, чтобы, например, можно было переименовывать поля без нарушения существующего кода.

Java-программисты абсолютно зависимы от ненужных инкапсуляторов. Они смотрят на публичное финальное поле и содрогаются в суеверном отвращении. Таким образом, мы получаем людей, делающих сумасшедшие рефлекторные заявления типа «Нет смысла в доступе к вашим полям напрямую (основной принцип программирования — инкапсуляция)», вместе с безумными рассуждениями о том, что разумно предписывать соглашение об именах (get/set и причудливо is) как единственный правильный способ обращения к данным, несмотря на то, что вы понятия не имеете, что на самом деле делают эти реализации методов.

Конечно, причина, по которой он сохраняется, заключается в непонятном решении языка не реализовывать свойства как встроенную функцию языка (а-ля C#, Kotlin) в любой момент за последние 30 лет. Вместо этого потратить десятилетие на неоднократные безуспешные попытки модульности языка (практически неиспользуемая функция с тех пор, как она наконец появилась).

Внедрение Records было бы прекрасной возможностью правильно реализовать свойства раз и навсегда (в конце концов, это до смешного простое улучшение — реализовать его в проходе desugar компилятора, и это работа дня, я сделал это сам; еще пару дней, чтобы добавить поддержку прослушивателя свойств во все доступные поля). Но все же нет.

Итак, разглагольствование, вернемся к вопросу. Открытые конечные поля были бы более разумной реализацией с возможностью сделать поле закрытым (), где инкапсуляция была абсолютно необходима. Более того, можно было бы легко реализовать автоматическую обертку коллекций/карт в неизменяемых декораторах (объявление и автоматически сгенерированный конструктор гарантируют, что поле получает неизменяемый), удаляя единственный убедительный аргумент в пользу автоматической инкапсуляции неизменяемого поля POJO.

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

Другие вопросы по тегам