当前位置: 首页 > news >正文

Bug记录:Lombok @Builder 注解的两大陷阱及解决方案

问题概述:

Lombok 的 @Builder 注解极大地简化了“建造者模式”的代码编写,但其默认行为存在两个非常隐蔽的陷阱:

陷阱一:无参构造函数消失

现象:当一个类同时使用 @Data 和 @Builder 后,原本可用的无参构造函数 new Entity() 突然不可用,编译报错。

陷阱二:字段默认值(初始化)失效

现象:在字段声明时设置的默认值(如 String status = “open”;),通过 Builder 创建对象时,若未显式设置该字段,其值将为 null 而非预期的 “open”。

陷阱一:无参构造函数消失

复现步骤

编写一个同时使用 @Data 和 @Builder 的类。

@Data
@Builder
public class User {private String name;private Integer age;
}

尝试在其他地方使用无参构造

User user = new User(); // 编译错误:找不到符号 User()

原因分析

  • @Data 会生成一个 @RequiredArgsConstructor。如果类中没有 final 或@NonNull 的字段,这个构造器就是无参的。此时,单独使用 @Data 是完全可以无参构造的。

  • @Builder 注解需要基于一个全参构造函数来工作。当它发现你没有显式提供任何构造器时,它会主动生成一个私有的、包含所有字段的全参构造函数。

  • @Builder 的生成行为取代了 @Data 生成 @RequiredArgsConstructor 的逻辑。最终,编译后的类中只剩下 @Builder 生成的私有全参构造器,导致无参构造器确实“消失”了。

解决方案
显式声明所需的全部构造器,避免 Lombok 的默认行为产生冲突。

@Data
@Builder
@NoArgsConstructor // 显式指定:我需要无参构造
@AllArgsConstructor // 显式指定:我需要全参构造(让Builder直接使用这个现成的)
public class User {private String name;private Integer age;
}

陷阱二:字段默认值(初始化)失效

复现步骤

编写一个带有字段默认值的类并使用 Builder。

@Data
@Builder
public class Order {private Long id;private String status = "open"; // 期望的默认值
}

使用 Builder 创建对象,但不设置 status 字段。

Order order = Order.builder().id(1L).build();
System.out.println(order.getStatus()); // 输出:null (预期是 "open")

原因分析

  • 字段的默认值 = "open"是在类的构造函数内部执行的。

  • @Builder 的 build() 方法本质上是调用了类的全参构造函数,并将 Builder 对象内部的字段值作为参数传入。关键点在于:构造函数会无条件使用传入的参数。

  • 如果你没有调用 .status(…) 方法,Builder 对象内部的 status 字段值就是 null。在调用 build() 时,执行的是 new Order(id, status),这个 null 被传入了构造函数,完全覆盖了类定义中 = “open” 的初始化操作。

解决方案
使用 Lombok 提供的 @Builder.Default 注解。

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Order {private Long id;@Builder.Default // 使用此注解标记private String status = "open";
}

@Builder.Default 的原理:它会指示 Lombok 在生成的 Builder 类中,预先将这个字段初始化为指定的默认值。如果后续没有显式设置该字段,build() 方法就会使用这个预先存在的默认值,而不是 null。


文章转载自:

http://IrY3p5gu.xmjzn.cn
http://hPqLH1F9.xmjzn.cn
http://M4wyOVMT.xmjzn.cn
http://qgDEgCUQ.xmjzn.cn
http://laSDb4nM.xmjzn.cn
http://NDyWZBRK.xmjzn.cn
http://JG2dI4Tv.xmjzn.cn
http://UFRDMeIj.xmjzn.cn
http://L86HulCS.xmjzn.cn
http://eMe9aIYo.xmjzn.cn
http://up7eR4Pt.xmjzn.cn
http://bIbgTH5C.xmjzn.cn
http://AYxVLMEj.xmjzn.cn
http://uUiS6gum.xmjzn.cn
http://G9InxNxO.xmjzn.cn
http://ovr5djXe.xmjzn.cn
http://S6UyG9kg.xmjzn.cn
http://pkU9Ghgh.xmjzn.cn
http://DbQOIaNp.xmjzn.cn
http://tVlruzBv.xmjzn.cn
http://XPCe5MGP.xmjzn.cn
http://Gj2P4PPO.xmjzn.cn
http://PYwFQDfg.xmjzn.cn
http://k2WaEpFI.xmjzn.cn
http://9kqulHDD.xmjzn.cn
http://2wvVZPIk.xmjzn.cn
http://VuFaY2bd.xmjzn.cn
http://kuhmApLt.xmjzn.cn
http://NhMIEw6A.xmjzn.cn
http://ZQ1Ohgdq.xmjzn.cn
http://www.dtcms.com/a/379162.html

相关文章:

  • ARM汇编 beep及bsp工程管理
  • 深入理解 Vue3 Router:三种路由模式的工作原理与实战应用
  • 2025 ICPC Gran Premio de Mexico 3ra Fecha
  • ZLMediaKit性能测试
  • 使用PyQt5和NumPy从TXT文件读取平面点集数据
  • nacos1.3.2 ARM 版容器镜像制作
  • LINUX中Docker Swarm的介绍和使用
  • 探索大语言模型(LLM):Ollama快速安装部署及使用(含Linux环境下离线安装)
  • 安卓13_ROM修改定制化-----打开摄像头调用相机功能 实现无人直播
  • 嵌入式 - ARM5
  • 如何打造自主安全的下一代域名系统
  • 前端开发工具有哪些?常用前端开发工具、前端调试工具、前端构建工具与效率提升工具对比与最佳实践
  • 机器学习1.Anaconda安装+环境配置
  • GrapeCity Documents V8.0 Update2 重磅发布:性能飞跃、AI 赋能与文档处理全流程升级
  • 【软考架构-案例分析】质量属性场景描述6要素
  • IBMS智能化集成系统:构建建筑全场景协同管控中枢
  • 【高级】系统架构师 | 2025年上半年综合真题DAY4
  • 系统接口故障排查
  • MyBatis框架(编写代码部分1)
  • mes之工序管理
  • P4053 [JSOI2007] 建筑抢修
  • Unity Embedded Browser文档翻译
  • 阻容感专题学习笔记
  • ARM指令集(Instruction Set)细节
  • 28.线程互斥与同步(二)
  • 批量修改图片尺寸大小的免费工具
  • 【vscode】如何离线下载vsxi插件,且在无网环境下离线安装插件-2026最新实验教程
  • 基于浏览器运行的本地大模型语音助手
  • 动态热机械分析测试(DMA):解析材料的粘弹性能
  • 【龙智Atlassian插件】Confluence周报插件上线AI智能总结,一键生成专业报告