为什么 Lombok 的 @Builder 注解与这个构造函数不兼容?

50

我有这个简单的代码:

@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. 如果需要同时使用构建器和构造函数,该怎么编译代码?

从错误中我推断出以下两点:1)构造函数参数数量不正确;2)传递给构造函数的参数类型不正确。 - Marios Nikolaou
那是发生在所有构造函数上还是特定的一个上?即使更改构造函数的参数,您是否仍会收到错误? - wdc
@wdc 我只有一个构造函数(在代码中已经提到)。我需要带有这个参数的构造函数才能复制对象。 - IKo
1
你检查过@Builder(toBuilder = true)了吗?它应该给你复制构造函数的功能。Foo copy = original.toBuilder().build() - wdc
@wdc,我刚试了你的解决方案。比使用构造函数还要好。谢谢! - IKo
3个回答

64
你可以添加一个@AllArgsConstructor注解,因为

@Builder如果没有定义其他构造函数,则会生成一个全参构造函数。

(引用@Andrew Tobilko)

或者将属性设置为@Builder: @Builder(toBuilder = true) 这样可以获得复制构造函数的功能。

@Builder(toBuilder = true)
class Foo {
    // fields, etc
}

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

虽然这是一种更简洁的方式,并且得到了作者的支持,但它也是违反直觉的,并涉及创建一个不必要的实例(这里是 foo.toBuilder())。 - Andrew Tobilko

34

当您提供自己的构造函数时,Lombok不会创建带有@Builder使用的所有参数的构造函数。因此,您应该在您的类中添加注释@AllArgsConstructor

@Data //try to avoid as it's an anti-pattern
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RegistrationInfo {
    //...
}

14

大概来说,@Builder 会在没有其他构造函数定义的情况下生成一个全参构造函数。

@Data
@Builder
@AllArgsConstructor(access = AccessLevel.PRIVATE)
class RegistrationInfo {

    private String mail;
    private String password;

    private RegistrationInfo(RegistrationInfo registrationInfo) {
        this(registrationInfo.mail, registrationInfo.password);
    }
}

2
在我的情况下,我使用默认构造函数,因此我被迫添加这个注释 @NoArgsConstructor - Bludwarf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接