0

Почему аннотация @Builder из Lombok несовместима с этим конструктором?

16

У меня есть такой простой код:

@Data
@Builder
public class RegistrationInfo {

    private String mail;
    private String password;

    public RegistrationInfo(RegistrationInfo registrationInfo) {
        this.mail = registrationInfo.mail;
        this.password = registrationInfo.password;
    }
}

Сначала я использовал только аннотацию @Builder от Lombok, и всё работало нормально. Но после того, как я добавил конструктор, код перестал компилироваться. Ошибка следующая:

Error:(2, 1) java: constructor RegistrationInfo in class com.user.RegistrationInfo cannot be applied to given types;
  required: com.user.RegistrationInfo
  found: java.lang.String,java.lang.String
  reason: actual and formal argument lists differ in length

У меня есть два вопроса:

  1. Почему аннотация Lombok @Builder не совместима с этим конструктором?
  2. Как сделать так, чтобы код компилировался, учитывая, что мне нужны и билдера, и конструктор?

3 ответ(ов)

0

Вы можете либо использовать аннотацию @AllArgsConstructor, потому что

@Builder генерирует конструктор с параметрами, если не определены другие конструкторы.

(Цитируя @Andrew Tobilko)

Либо установить атрибут у @Builder: @Builder(toBuilder = true). Это даст вам функциональность конструктора копирования.

@Builder(toBuilder = true)
class Foo {
    // поля и т.д.
}

Foo foo = getReferenceToFooInstance();
Foo copy = foo.toBuilder().build();

Таким образом, если вам нужно создать копию объекта, добавьте toBuilder = true и используйте метод toBuilder().

0

Когда вы предоставляете свой собственный конструктор, Lombok не создает конструктор с параметрами, который используется аннотацией @Builder. Поэтому вам нужно просто добавить аннотацию @AllArgsConstructor к вашему классу:

@Data // старайтесь избегать этой аннотации, так как она считается антипаттерном
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RegistrationInfo {
    //...
}

Таким образом, вы получите доступ к конструктору с параметрами и возможность использовать @Builder без проблем.

0

В данном примере использование аннотации @Builder в сочетании с явным определением конструктора может вызывать некоторые вопросы. Давайте разберем это подробнее.

Когда вы используете аннотацию @Builder в классе, она действительно генерирует билдер с полями класса. Однако, в вашем коде есть также аннотация @AllArgsConstructor(access = AccessLevel.PRIVATE), которая указывает на то, что должен быть сгенерирован конструктор с аргументами для всех полей, но с приватным уровнем доступа.

Ваша реализация конструктора private RegistrationInfo(RegistrationInfo registrationInfo) является дополнительным частным конструктором, который принимает объект RegistrationInfo и, вероятно, предназначен для выполнения определенной логики копирования.

Таким образом, если в классе не определены дополнительные конструкторы, то @Builder действительно будет генерировать конструктор с фиксированными параметрами для всех полей. Однако в вашем случае наличие конструктора с параметром RegistrationInfo и конструктора с @AllArgsConstructor может привести к тому, что поведение @Builder будет отличаться.

Итак, в общем случае, если нет определенных других конструкторов, то возможно, что @Builder создаст конструктор со всеми аргументами, даже если вы используете @AllArgsConstructor. Но так как у вас есть несколько специально определенных конструкторов, необходимо проверять, как будет работать билдер в результате.

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

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь