Геттеры и сеттеры в Java: концепция JavaBeans - Вопросы

Всего: 5 вопросов

1. 

Что такое геттеры и сеттеры в Java и по каким правилам они называются?

Геттер — это public метод, который возвращает значение поля; сеттерpublic метод, который присваивает полю новое значение. Поля при этом объявляют private, поэтому обратиться к ним извне можно только через эти методы. Имя метода строится механически: берётся имя свойства, первая буква переводится в верхний регистр и добавляется префикс: namegetName() / setName(String). Геттер не принимает параметров и возвращает тип свойства; сеттер возвращает void и принимает ровно один параметр того же типа. Для примитивного boolean вместо get разрешён префикс is: isPrinted(). Пара таких методов образует свойство (property) класса, причём имя свойства определяется именами методов, а не именем поля.

2. 

Когда геттер можно назвать с префиксом is, а когда только get?

Префикс is спецификация JavaBeans разрешает только для свойства примитивного типа boolean: isEnabled() и getEnabled() здесь равноправны, но is идиоматичнее — именно его генерируют IDE. Если поле имеет тип обёртки Boolean, допустим только getArchived(): класс java.beans.Introspector проверяет возвращаемый тип и метод isArchived() с типом Boolean свойством не признаёт. Практическое следствие: после замены boolean на Boolean ради поддержки null свойство молча пропадает из JSP EL, JavaFX и Spring BeanWrapper (Jackson при этом более снисходителен и is-геттер примет). Сеттер в обоих случаях называется одинаково — setEnabled(...).

3. 

Каким требованиям должен отвечать класс, чтобы называться JavaBean, и зачем ему конструктор без аргументов?

JavaBean — это обычный Java-класс, оформленный по соглашению: он объявлен public, имеет public конструктор без аргументов, хранит состояние в private полях, открывает его через геттеры и сеттеры по правилам именования и (по спецификации) реализует Serializable. Конструктор без аргументов нужен потому, что фреймворк создаёт объект через рефлексию, ничего не зная о параметрах вашего конструктора: сначала вызывается new без аргументов, затем свойства заполняются сеттерами. Так работают Hibernate при загрузке сущности из базы и Jackson при разборе JSON. Как только в классе появляется конструктор с параметрами, конструктор по умолчанию исчезает, и приложение падает уже во время выполнения: InstantiationException у Hibernate, InvalidDefinitionException у Jackson. Объявляйте его явно.

4. 

Для чего нужны геттеры и сеттеры, если поле можно объявить public?

Открытое поле позволяет привести объект в невозможное состояние: у класса с полями radius и diam присваивания circle.diam = 25; circle.radius = 10; компилятор пропустит, потому что Java проверяет типы, а не смысл. Ошибка проявится далеко от места возникновения. Сеттер даёт классу единственную точку входа для изменения состояния: в нём можно проверить аргумент (IllegalArgumentException на отрицательный радиус) и пересчитать связанные поля (this.diam = radius * 2), то есть сохранить инвариант. Геттер, в свою очередь, может вернуть вычисленное значение или защитную копию коллекции. Дополнительно методы доступа позволяют менять внутреннее устройство класса, не ломая вызывающий код, и делают класс пригодным для фреймворков, работающих по соглашению JavaBeans.

5. 

Чем record отличается от JavaBean и когда что выбирать?

record (Java 16+) сам генерирует private final поля, конструктор со всеми параметрами, equals(), hashCode(), toString() и методы доступа. Но методы доступа называются по имени компонента без префикса: person.fullName(), а не getFullName(), и person.retired(), а не isRetired(). Record неизменяем: сеттеров нет в принципе, конструктор без аргументов невозможен, класс неявно final. Формально record не является JavaBean, и всё, что опирается на java.beans.Introspector, свойств у него не найдёт; современные библиотеки поддерживают records напрямую (Jackson — с версии 2.12). Выбирайте record для DTO, ответов API, ключей и результатов запросов; классический JavaBean с геттерами и сеттерами нужен там, где объект должен изменяться или где этого требует фреймворк — прежде всего для сущностей JPA/Hibernate.

Страница 1 из 1