Цикл статей «Project Lombok».
Следующая статья — «Lombok @Data».
Предыдущая статья — «Lombok @EqualsAndHashCode — облегчаем сравнение объектов».
Эти три аннотации генерируют конструктор, который принимает 1 параметр для определённых полей и просто присваивает этот параметр полю.
@NoArgsConstructor генерирует конструктор без параметров. Если это невозможно (потому что поля final), то возникает ошибка компиляции. Если используется @NoArgsConstructor(force = true), то все final поля инициализируются 0 / false / null. Для полей с ограничениями, например @NotNull, никаких проверок при присвоении не генерируется, поэтому эти условия могут не выполняться, пока эти поля не будут инициализированы подобающим образом позже. Определённые Java-конструкции, например Hibernate и Service Provider Interface требуют наличия конструктора без аргументов. Эта конструкция используется главным образом вместе с @Data или одной из других аннотаций, генерирующих конструктор.
@RequiredArgsConstructor генерирует конструктор с 1 параметром для каждого поля, которое требует специальной обработки. Все неинициализированные final поля получают параметр, также как все остальные поля, помеченные @NonNull, которые не иницилизированы при объявлении. Для этих случаев также генерируется явная проверка на null. Конструктор бросает исключение NullPointerException, если какой-либо из параметров, предназначенный для полей, помеченных @NonNull содержит null. Порядок этих параметров совпадает с порядком появления полей в классе.
@AllArgsConstructor генерирует конструктор с одним параметром для каждого поля в классе. Поля, помеченные @NonNull, имеют проверку на null для этих параметров.
Каждая из этих аннотаций имеет альтернативную форму, где сгенерированный конструктор всегда приватный, и генерируется дополнительный статический фабричный метод, оборачивающий этот конструктор. Этот режим включается с помощью параметра staticName в аннотации, например: @RequiredArgsConstructor(staticName="of"). Такой статический метод выводит шаблоны в отличие от нормального конструктора. Это означает, что пользователи вашего API смогут писать MapEntry.of("foo", 5) , вместо new MapEntry<String, Integer>("foo", 5) .
Для того чтобы добавить аннотации к сгенерированным конструкторам, вы можете использовать onConstructor=@__({@AnnotationsHere}), но будьте осторожны, так как это экспериментальная возможность.
Статические поля пропускаются этими аннотациями. Также аннотация @java.beans.ConstructorProperties добавляется ко всем конструкторам, у которых хотя бы один аргумент, что позволяет утилитам редактирования вызывать сгенерированные конструкторы. @ConstructorProperties сейчас находится в Java 1.6, что означает, что если ваш код будет компилироваться в Java 1.5, то возникнет ошибка компиляции. Запуск на JVM 1.5 должен проходить без проблем (аннотация игнорируется). Чтобы подавить генерацию аннотации @ConstructorProperties, добавьте параметр к вашим аннотациям: @AllArgsConstructor(suppressConstructorProperties=true) . Однако как только Java 1.5, время время которой уже прошло, уйдёт в забвение, этот параметр будет удалён. Поэтому он помечен как устаревший.
В отличие от большинства других аннотаций Lombok, существование явного конструктора не предотвращает генерацию этими аннотациями своих собственных конструкторов. Это означает, что вы можете написать свой специализированный конструктор, и позволить Lombok сгенерировать свои как положено. Если возникнет конфликт (один из ваших конструкторов заканчивается той же сигнатурой,что и сгенерированный Lombok), то возникнет ошибка компиляции.
С использованием Lombok
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import lombok.AllArgsConstructor; import lombok.NonNull; @RequiredArgsConstructor(staticName = "of") @AllArgsConstructor(access = AccessLevel.PROTECTED) public class ConstructorExample<T> { private int x, y; @NonNull private T description; @NoArgsConstructor public static class NoArgsExample { @NonNull private String field; } } |
Чистая Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
public class ConstructorExample<T> { private int x, y; @NonNull private T description; private ConstructorExample(T description) { if (description == null) throw new NullPointerException("description"); this.description = description; } public static <T> ConstructorExample<T> of(T description) { return new ConstructorExample<T>(description); } @java.beans.ConstructorProperties({ "x", "y", "description" }) protected ConstructorExample(int x, int y, T description) { if (description == null) throw new NullPointerException("description"); this.x = x; this.y = y; this.description = description; } public static class NoArgsExample { @NonNull private String field; public NoArgsExample() { } } } |
Поддерживаемые ключи конфигурации
1 |
lombok.anyConstructor.suppressConstructorProperties = [true | false] (default: false) |
Если установлено в true, то Lombok пропускает добавление @java.beans.ConstructorProperties к генерируемым конструкторам. Это полезно при разработка под Andoird или GWT, где эта аннотация не всегда доступна.
1 |
lombok.[allArgsConstructor|requiredArgsConstructor|noArgsConstructor].flagUsage = [warning | error] (default: not set) |
Lombok будет помечать любое использование указанной аннотации (@AllArgsConstructor, @RequiredArgsConstructor или @NoArgsConstructor) как предупреждение или ошибку, если настроено.
1 |
lombok.anyConstructor.flagUsage = [warning | error] (default: not set) |
Lombok будет помечать любое использование любой их трёх аннотаций, генерирующих конструкторы, предупреждением или ошибкой, если настроено.
Примечание
Даже если поле явно инициализировано значением null, Lombok будет рассматривать необходимость избегать null, и не будет рассматривать поле в качестве обязательного аргумента. Считается, что если вы явно присваиваете null полю, которое вы пометили как @NonNull, то вы знаете, что делаете.
Аннотация @java.beans.ConstructorProperties никогда не генерируется для конструктора без аргументов. Это также объясняет, почему в аннотации @NoArgsConstructor нет suppressConstructorProperties. Аннотация @ConstructorProperties также пропускается для приватных конструкторов. Сгенерированный статический фабричный метод также не получает @ConstructorProperties, так как эта аннотация может быть добавлена только для реальных конструкторов.
@XArgsConstructor может использоваться и при объявлении перечислений. Сгенерированный конструктор будет всегда приватным, потому что не приватные конструкторы запрещены для перечислений. Вам не нужно указывать AccessLevel.PRIVATE.
Пока параметр suppressConstructorProperties помечен как устаревший в предвкушении того момента, когда все среды Java будут иметь аннотацию @ConstructorProperties. GWT 2.2 и Android 2.3.3, которые пока не имеют этих аннотаций, должны стать древней историей перед удалением этого параметра.
Конфигурационные ключи flagUsage не работают при генерации конструктора аннотациями @Data, @Value или любыми другими.
Цикл статей «Project Lombok».
Следующая статья — «Lombok @Data».
Предыдущая статья — «Lombok @EqualsAndHashCode — облегчаем сравнение объектов».