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

Lombok @Builder 注解的进阶玩法:自定义 Getter/Setter 方法全攻略

大家好呀!👋 今天我们来聊聊 Java 开发中超级实用的 Lombok 库,特别是它的 @Builder 注解。很多小伙伴都用过 @Builder 来简化对象的创建,但你们知道吗?当我们需要自定义 getter/setter 方法时,@Builder 也能玩出花样来!🤹‍♀️

一、Lombok @Builder 快速回顾 🏃‍♂️

首先,让我们快速回顾一下 @Builder 的基本用法:

@Builder
public class User {private String name;private int age;private String email;
}

这样就能用链式调用来创建对象啦:

User user = User.builder().name("张三").age(25).email("zhangsan@example.com").build();

超方便的有没有!😍 但有时候,我们需要对字段进行一些特殊处理,这时候就需要自定义 getter/setter 了。

二、为什么需要自定义 Getter/Setter?🤔

想象一下这些场景:

  • 你想在设置年龄时检查是否合法(比如不能为负数)
  • 你想在获取邮箱时自动转为小写
  • 你想对某些字段进行加密/解密处理

这时候,默认的 getter/setter 就不够用了,我们需要自己动手!🛠️

三、自定义 Getter/Setter 的正确姿势 🧘‍♀️

1. 基本方法:手动添加 getter/setter

最简单的方法就是自己写:

@Builder
public class User {private String name;private int age;private String email;// 自定义 getterpublic String getEmail() {return email != null ? email.toLowerCase() : null;}// 自定义 setterpublic void setAge(int age) {if (age < 0) {throw new IllegalArgumentException("年龄不能为负数!");}this.age = age;}
}

但是!这样直接添加 getter/setter 会导致 @Builder 生成的 builder 类忽略你的自定义方法。😱

2. 正确方法:使用 @Getter 和 @Setter

Lombok 提供了更优雅的解决方案:

@Builder
@Getter
@Setter
public class User {private String name;private int age;@Getter(AccessLevel.NONE)  // 不自动生成 getter@Setter(AccessLevel.NONE)  // 不自动生成 setterprivate String email;// 自定义 getterpublic String getEmail() {return email != null ? email.toLowerCase() : null;}// 自定义 setterpublic void setAge(int age) {if (age < 0) {throw new IllegalArgumentException("年龄不能为负数!");}this.age = age;}
}

这样,@Builder 就会使用你自定义的方法啦!🎉

四、更高级的玩法:Builder 自定义方法 🚀

有时候,我们想在 builder 阶段就进行验证或处理:

1. 自定义 builder 方法

@Builder
public class User {private String name;private int age;private String email;// 自定义 builder 类public static class UserBuilder {private int age;public UserBuilder age(int age) {if (age < 0) {throw new IllegalArgumentException("年龄不能为负数!");}this.age = age;return this;}}
}

这样,在 builder 阶段就会进行验证:

// 这会抛出异常
User user = User.builder().name("张三").age(-5)  // 这里会抛异常.email("zhangsan@example.com").build();

2. 使用 @Builder.Default 设置默认值

@Builder
public class User {private String name;@Builder.Defaultprivate int age = 18;  // 默认值private String email;
}

五、实战案例:完整的自定义处理 📝

让我们看一个完整的例子:

@Builder
@Getter
public class SecureUser {private String username;@Setter(AccessLevel.NONE)private String password;// 自定义密码设置方法public void setPassword(String password) {if (password.length() < 8) {throw new IllegalArgumentException("密码至少需要8位!");}this.password = encrypt(password);  // 假设有加密方法}// 自定义 builder 方法public static class SecureUserBuilder {private String password;public SecureUserBuilder password(String password) {if (password.length() < 8) {throw new IllegalArgumentException("密码至少需要8位!");}this.password = encrypt(password);return this;}}// 模拟加密方法private static String encrypt(String input) {return "加密后的:" + input;  // 实际项目中请使用真正的加密算法}
}

使用示例:

// 正确用法
SecureUser user = SecureUser.builder().username("admin").password("12345678")  // 满足长度要求.build();// 错误用法会抛异常
SecureUser invalidUser = SecureUser.builder().username("admin").password("123")  // 这里会抛异常.build();

六、常见问题解答 ❓

Q: 为什么我的自定义 getter/setter 不生效?
A: 可能是因为 Lombok 自动生成了默认方法覆盖了你的自定义方法。记得用 @Getter(AccessLevel.NONE)@Setter(AccessLevel.NONE) 来禁用自动生成。

Q: 可以在 builder 中使用自定义方法吗?
A: 当然可以!就像上面的例子,你可以自定义 builder 类中的方法。

Q: @Builder 和 @Data 一起用会怎样?
A: @Data 包含了 @Getter@Setter 等功能,可以和 @Builder 一起用,但要注意方法覆盖的问题。

七、总结 🎯

今天我们一起探索了 Lombok @Builder 注解与自定义 getter/setter 方法的完美配合:

  1. 使用 @Getter/@Setter 配合 AccessLevel.NONE 来控制自动生成
  2. 直接在类中定义自定义 getter/setter 方法
  3. 通过自定义 builder 类方法来增强 builder 的功能
  4. 使用 @Builder.Default 设置默认值

记住,虽然 Lombok 能帮我们减少样板代码,但遇到特殊需求时,我们完全可以"夺回控制权"!💪

希望这篇文章对你有帮助!如果有任何问题,欢迎在评论区留言讨论~ 😊

Happy coding! 🚀

推荐阅读文章

  • 由 Spring 静态注入引发的一个线上T0级别事故(真的以后得避坑)

  • 如何理解 HTTP 是无状态的,以及它与 Cookie 和 Session 之间的联系

  • HTTP、HTTPS、Cookie 和 Session 之间的关系

  • 什么是 Cookie?简单介绍与使用方法

  • 什么是 Session?如何应用?

  • 使用 Spring 框架构建 MVC 应用程序:初学者教程

  • 有缺陷的 Java 代码:Java 开发人员最常犯的 10 大错误

  • 如何理解应用 Java 多线程与并发编程?

  • 把握Java泛型的艺术:协变、逆变与不可变性一网打尽

  • Java Spring 中常用的 @PostConstruct 注解使用总结

  • 如何理解线程安全这个概念?

  • 理解 Java 桥接方法

  • Spring 整合嵌入式 Tomcat 容器

  • Tomcat 如何加载 SpringMVC 组件

  • “在什么情况下类需要实现 Serializable,什么情况下又不需要(一)?”

  • “避免序列化灾难:掌握实现 Serializable 的真相!(二)”

  • 如何自定义一个自己的 Spring Boot Starter 组件(从入门到实践)

  • 解密 Redis:如何通过 IO 多路复用征服高并发挑战!

  • 线程 vs 虚拟线程:深入理解及区别

  • 深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别

  • 10大程序员提升代码优雅度的必杀技,瞬间让你成为团队宠儿!

  • “打破重复代码的魔咒:使用 Function 接口在 Java 8 中实现优雅重构!”

  • Java 中消除 If-else 技巧总结

  • 线程池的核心参数配置(仅供参考)

  • 【人工智能】聊聊Transformer,深度学习的一股清流(13)

  • Java 枚举的几个常用技巧,你可以试着用用

  • 由 Spring 静态注入引发的一个线上T0级别事故(真的以后得避坑)

  • 如何理解 HTTP 是无状态的,以及它与 Cookie 和 Session 之间的联系

  • HTTP、HTTPS、Cookie 和 Session 之间的关系

  • 使用 Spring 框架构建 MVC 应用程序:初学者教程

  • 有缺陷的 Java 代码:Java 开发人员最常犯的 10 大错误

  • Java Spring 中常用的 @PostConstruct 注解使用总结

  • 线程 vs 虚拟线程:深入理解及区别

  • 深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别

  • 10大程序员提升代码优雅度的必杀技,瞬间让你成为团队宠儿!

  • 探索 Lombok 的 @Builder 和 @SuperBuilder:避坑指南(一)

  • 为什么用了 @Builder 反而报错?深入理解 Lombok 的“暗坑”与解决方案(二)

相关文章:

  • 在没有第三方库的情况下使用 Python 自带函数解码
  • 3.串口通信之SPI
  • Java学习手册:Java内存模型
  • 22、字节与字符的概念以及二者有什么区别?
  • 【Python爬虫基础篇】--1.基础概念
  • MCP Server和Client的基本使用方法
  • halcon模板匹配(八)alignment_for_ocr_in_semiconductor
  • OCR:开启文档抽取的智能变革之门
  • 4.16 AT好题选做
  • 探索关系型数据库 MySQL
  • LFI to RCE
  • DiffuRec: A Diffusion Model for Sequential Recommendation
  • 将二进制的stl文件转换为ascii的形式
  • stm32F103、GD32F103读写Nor Flash实战指南
  • 吉利矩阵(DFS)
  • [AI]浅谈大模型应用开发的认知构建
  • ecovadis审核有什么原则?什么是ecovadis审核,有什么意义
  • 递归函数详解
  • Langchain-构建向量数据库和检索器
  • 【APM】NET Traces, Metrics and Logs to OLTP
  • 一场与纪录并行的伦敦马拉松,超40项新世界纪录诞生
  • 我国将出台稳就业稳经济推动高质量发展若干举措,将根据形势变化及时出台增量储备政策
  • 中日友好医院通报“医师肖某被举报”:基本属实,开除党籍并解聘
  • 王文涛会见德国汽车工业协会主席穆勒
  • 没有雷军的车展:老外扎堆,萌车、机器狗谁更抢镜?| 湃客Talk
  • 地下管道密布成难题,道路修整如何破局?