You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Lombok 1.18.24能否同时生成必填参数构造器与Builder?

解决方案:同时生成指定构造器与Builder(Lombok 1.18.24)

可以实现需求,以下是两种可行方案:

方案一:手动组合注解替代@Value

避免@Value自动生成私有全参构造器导致的Builder冲突,手动组合@Value的等效注解,配合@RequiredArgsConstructor生成目标构造器:

import lombok.AccessLevel;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.FieldDefaults;

@Getter
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@ToString
@EqualsAndHashCode
@RequiredArgsConstructor // 生成仅接收alpha的构造器
@Builder
class Foo {
    String alpha;
    @Builder.Default String bravo = "x";

    static void bar() {
        // 使用目标构造器
        Foo foo1 = new Foo("y");
        // 使用Builder(bravo默认值为"x")
        Foo foo2 = Foo.builder().alpha("y").build();
        // 使用Builder自定义bravo
        Foo foo3 = Foo.builder().alpha("y").bravo("z").build();
    }
}

说明:

  • @FieldDefaults实现@Value的「字段私有+不可变」特性;
  • @RequiredArgsConstructor会自动识别未初始化的final字段(仅alpha),生成对应构造器;
  • @Builder结合@Builder.Default生成支持默认值的Builder,内部会自动生成全参构造器用于实例化,与目标构造器共存不冲突。

方案二:基于@Value手动补充构造器

如果必须使用@Value,可以手动覆盖其生成的私有全参构造器,同时添加目标单参构造器:

import lombok.Builder;
import lombok.Value;

@Value
@Builder
class Foo {
    String alpha;
    @Builder.Default String bravo = "x";

    // 手动定义public全参构造器,供Builder调用
    public Foo(String alpha, String bravo) {
        this.alpha = alpha;
        this.bravo = bravo;
    }

    // 生成仅接收alpha的构造器,复用全参构造器传入默认值
    public Foo(String alpha) {
        this(alpha, "x");
    }

    static void bar() {
        new Foo("y"); // 调用目标构造器
        Foo.builder().alpha("y").build(); // Builder使用全参构造器,自动传入bravo默认值
    }
}

说明:

  • @Value原本会生成私有全参构造器,手动定义public全参构造器后,Builder可以正常访问并使用它;
  • 单参构造器通过调用全参构造器传入默认值,保证final字段bravo被正确初始化,避免编译错误。

你之前报错的原因分析

  1. 第一种方案(仅@Value+@Builder+手动构造器):
    @Value生成的全参构造器是私有,Builder无法访问,只能尝试调用你手动写的单参构造器,但Builder需要传入两个参数(alpha+bravo),导致参数长度不匹配报错。同时你手动构造器未显式初始化final字段bravo,违反Java语法规范。

  2. 第二种方案(加@AllArgsConstructor):
    @AllArgsConstructor生成的全参构造器会覆盖@Value的私有构造器,但你手动写的单参构造器未初始化bravo,final字段必须被初始化,因此编译报错。

  3. 第三种方案(加@RequiredArgsConstructor):
    在Lombok 1.18.24中,@Builder.Default不会被@RequiredArgsConstructor识别为「已初始化字段」,因此生成的构造器仍包含bravo参数,导致你调用new Foo("y")时参数数量不匹配。

  4. 第四种方案(同时加两个构造器注解):
    @AllArgsConstructor和@RequiredArgsConstructor生成了签名完全相同的构造器(都包含alpha和bravo),导致重复定义报错。


内容的提问来源于stack exchange,提问作者Hollis Waite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 08:31:16