@Builder注解详解:巧妙避开常见的陷阱

欢迎来到我的博客,代码的世界里,每一行都是一个故事


在这里插入图片描述

🎏:你只管努力,剩下的交给时间

🏠 :小破站

@Builder注解详解:巧妙避开常见的陷阱

    • 前言
    • 1. @Builder的基本使用
      • 使用示例
        • 示例类
        • 创建对象
      • 主要功能
      • 高级用法
        • 自定义构建方法
        • 使用 `@Builder.Default`
      • 依赖配置
        • Maven
        • Gradle
    • 2. 常见的隐藏陷阱
    • 3. 实用的解决方案和最佳实践
      • 知识点总结

前言

在Java开发中,我们经常会遇到需要创建复杂对象的情况。传统的构造函数和setter方法有时显得繁琐且不直观。这时候,Lombok的@Builder注解无疑成为了我们的救星,简化了对象创建的过程。然而,正所谓"世上没有免费的午餐",在享受@Builder带来的便利时,我们也需要警惕那些潜藏的陷阱。今天,让我们一起揭开@Builder的神秘面纱,深入了解它的工作机制和常见问题,避免掉进那些意想不到的坑里。

1. @Builder的基本使用

@Builder 是 Lombok 库中的一个注解,用于实现 Builder 模式。Builder 模式是一种设计模式,通过提供一种灵活的方式来创建对象,尤其是在对象的构造参数较多时。Lombok 的 @Builder 注解可以自动生成一个内部 Builder 类,以及对应的构建方法,从而简化代码的编写。

使用示例

以下是 @Builder 的基本使用示例:

示例类
import lombok.Builder;
import lombok.ToString;@Builder
@ToString
public class User {private String name;private int age;private String email;
}
创建对象

使用 @Builder 自动生成的 Builder 类来创建对象:

public class Main {public static void main(String[] args) {User user = User.builder().name("John Doe").age(30).email("john.doe@example.com").build();System.out.println(user);}
}

在上述示例中,User 类使用了 @Builder 注解,Lombok 自动为该类生成了一个内部静态的 UserBuilder 类。通过 User.builder() 方法可以获取这个 UserBuilder 对象,并通过链式调用的方式设置属性,最后调用 build() 方法创建 User 对象。

主要功能

  1. 链式调用:通过链式调用的方式设置属性值,代码更简洁明了。
  2. 可选参数:可以选择性地设置参数,未设置的参数将使用默认值。
  3. 不可变对象:可以轻松创建不可变对象,通过 Builder 模式创建的对象是线程安全的。

高级用法

自定义构建方法

你可以自定义构建方法以进行额外的初始化或验证:

@Builder
@ToString
public class User {private String name;private int age;private String email;public static class UserBuilder {public User build() {// 进行额外的初始化或验证if (this.age < 0) {throw new IllegalArgumentException("Age cannot be negative");}return new User(name, age, email);}}
}
使用 @Builder.Default

当使用 @Builder 时,默认值可能会被忽略。可以使用 @Builder.Default 注解来指定默认值:

@Builder
@ToString
public class User {private String name;private int age;@Builder.Defaultprivate String email = "default@example.com";
}

依赖配置

要使用 Lombok 的 @Builder 注解,需要在项目中添加 Lombok 依赖。以下是 Maven 和 Gradle 的依赖配置示例:

Maven
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>最新版本号</version><scope>provided</scope>
</dependency>
Gradle
dependencies {compileOnly 'org.projectlombok:lombok:最新版本号'annotationProcessor 'org.projectlombok:lombok:最新版本号'
}

添加依赖后,需要在 IDE 中启用注解处理器,以便自动生成代码。

2. 常见的隐藏陷阱

陷阱一:无参构造函数缺失
当我们使用@Builder时,Lombok不会自动生成无参构造函数,这可能在某些情况下导致反射调用失败。

当你使用Lombok的@Builder注解时,它会自动生成一个静态的内部类,通常被称为Builder类,这个Builder类提供了一种构建对象的方法。但是,@Builder不会自动生成无参构造函数,这可能会导致在通过反射实例化类时出现问题。

而没有@Builder时,Java编译器会默认生成一个无参构造函数(如果没有定义任何构造函数),因此通过反射调用构造函数时不会报错。

解决方案
使用@NoArgsConstructor注解:

import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@Builder
@NoArgsConstructor
public class User {private String name;private int age;
}

陷阱二:与其他注解的兼容性问题
某些注解与@Builder可能存在兼容性问题,例如@JsonCreator和Jackson库的使用。

解决方案
手动编写Builder类或结合@JsonPOJOBuilder注解:

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import lombok.Builder;
import lombok.Data;@Data
@Builder
@JsonDeserialize(builder = User.UserBuilder.class)
public class User {private String name;private int age;@JsonPOJOBuilder(withPrefix = "")public static class UserBuilder {}
}

陷阱三:继承问题
在继承体系中使用@Builder可能会导致父类的属性无法正确初始化。

解决方案
使用@SuperBuilder注解:

import lombok.Data;
import lombok.experimental.SuperBuilder;@Data
@SuperBuilder
public class User {private String name;private int age;
}@Data
@SuperBuilder
public class Employee extends User {private String position;
}

3. 实用的解决方案和最佳实践

最佳实践一:结合其他注解使用
为了避免无参构造函数问题,建议在使用@Builder时总是加上@NoArgsConstructor@AllArgsConstructor注解。

最佳实践二:自定义Builder
在需要特殊逻辑或与其他库集成时,可以手动编写Builder类,确保完全掌控构建过程。

最佳实践三:注重代码可读性
虽然@Builder提供了强大的功能,但在使用时应注意代码的可读性,避免过度复杂化。必要时,提供清晰的文档和注释。

知识点总结

  1. @Builder的基本原理:了解@Builder的工作机制,掌握其基本用法。
  2. 无参构造函数的缺失:认识到@Builder不会自动生成无参构造函数,并学习如何使用@NoArgsConstructor解决此问题。
  3. 与其他注解的兼容性:了解@Builder与其他注解(如@JsonCreator)的兼容性问题,掌握解决方案。
  4. 继承体系中的问题:理解在继承体系中使用@Builder的限制,学习如何使用@SuperBuilder解决相关问题。
  5. 最佳实践:掌握一系列最佳实践,确保在使用@Builder时既能享受其便利,又能避免常见陷阱。

通过这篇文章,希望读者能够深入理解@Builder的工作机制,避免掉进常见的陷阱,并在实际开发中更加高效地使用这个强大的工具。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/43142.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

极客时间:使用Autogen Builder和本地LLM(Microsoft Phi3模型)在Mac上创建本地AI代理

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

pointpillar 代码报错

错误&#xff1a; Traceback (most recent call last): File "/home/gaoithe/project/python/code/CenterPoint/./tools/dist_test.py", line 415, in <module> main() File "/home/gaoithe/project/python/code/CenterPoint/./tools/dist_test.p…

运维系列.Nginx:自定义错误页面

运维系列 Nginx&#xff1a;自定义错误页面 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/…

本地部署秘塔开源搜索引擎

秘塔AI搜索是由秘塔科技于2024年初推出的一款新型搜索引擎&#xff0c;被业界誉为“中国版的Perplexity”。秘塔科技成立于2018年4月&#xff0c;其核心团队包括CEO闵可锐、技术专家唐悦和首席运营官王益为等。秘塔AI搜索以其高效简洁的特点受到关注&#xff0c;其搜索结果直接…

LeetCode——第 405 场周赛

题目 找出加密后的字符串 给你一个字符串 s 和一个整数 k。请你使用以下算法加密字符串&#xff1a; 对于字符串 s 中的每个字符 c&#xff0c;用字符串中 c 后面的第 k 个字符替换 c&#xff08;以循环方式&#xff09;。 返回加密后的字符串。 示例 1&#xff1a; 输入&…

数据结构(其二)--线性表

1. 基本概念 线性表&#xff1a; &#xff08;1&#xff09;.其中的各个元素&#xff0c;数据类型相同。 &#xff08;2&#xff09;.元素之间&#xff0c;有次序。 &#xff08;3&#xff09;.都有表头元素和表尾元素。 &#xff08;4&#xff09;.除了表头表尾&#xff…

谷粒商城学习笔记-16-人人开源搭建后台管理系统

文章目录 一&#xff0c;克隆前/后端代码1&#xff0c;克隆前端工程renren-fast-value2&#xff0c;克隆后端工程renren-fast 二&#xff0c;集成后台管理系统的后端代码三&#xff0c;启动后台管理系统四&#xff0c;前端系统的安装和运行1&#xff0c;下载安装VSCode2&#x…

为什么KV Cache只需缓存K矩阵和V矩阵,无需缓存Q矩阵?

大家都知道大模型是通过语言序列预测下一个词的概率。假定{ x 1 x_1 x1​&#xff0c; x 2 x_2 x2​&#xff0c; x 3 x_3 x3​&#xff0c;…&#xff0c; x n − 1 x_{n-1} xn−1​}为已知序列&#xff0c;其中 x 1 x_1 x1​&#xff0c; x 2 x_2 x2​&#xff0c; x 3 x_3 x…

拓展中国剩余定理

题目链接 代码&#xff1a; /*扩展中国剩余定理的使用范围更广泛&#xff0c;不要求模数全部互质扩展中国剩余定理&#xff1a;两两合并同余方程&#xff0c;合并 n - 1 次之后&#xff0c;就能求解合并两个同余方程&#xff1a;x ≡ r1 (mod p1) --- x a*p1 r1x ≡ r2 (mo…

from transformers.modeling_utils import PreTrainedModel

from transformers.modeling_utils import PreTrainedModel 是用于导入 Hugging Face Transformers 库中的 PreTrainedModel 类。这个类是所有预训练模型的基类&#xff0c;提供了许多通用功能和方法&#xff0c;适用于不同类型的模型&#xff08;如BERT、GPT、Transformer-XL等…

STM32对数码管显示的控制

1、在项目开发过程中会遇到STM32控制的数码管显示应用&#xff0c;这里以四位共阴极数码管显示控制为例讲解&#xff1b;这里采用的控制芯片为STM32F103RCT6。 2、首先要确定数码管的段选的8个引脚连接的单片机的引脚是哪8个&#xff0c;然后确认位选的4个引脚连接的单片机的4…

ChatGPT:fetch/xhr是什么意思

ChatGPT&#xff1a;fetch/xhr是什么意思 fetch 和 XHR&#xff08;XMLHttpRequest&#xff09;是两种用于在客户端与服务器之间进行异步通信的方法。在网页开发中&#xff0c;它们用于从服务器获取数据或将数据发送到服务器&#xff0c;而不需要刷新整个页面。 fetch fetch …

平滑切换/过渡多个控制器的方法

控制系统理论 在控制系统领域&#xff0c;平滑切换多个控制器通常指的是在保持系统稳定性和性能的同时&#xff0c;实现控制器之间的无缝切换。 输出抖动抑制方法&#xff1a;通过设计包含积分作用的控制器实现跟踪控制&#xff0c;并通过设计补偿器来减小控制输入信号在切换…

京东技术团队撰写的整整986页《漫画学Python》到底有什么魅力?

这是一本Python入门书。无论您是想学习编程的小学生&#xff0c;还是想参加计算机竞赛的中学生&#xff0c;抑或是计算机相关专业的大学生&#xff0c;甚至是正在从事软件开发的职场人&#xff0c;本书都适合您阅读和学习。但您若想更深入地学习Python并进行深层次应用&#xf…

第一个vue——01

指定vue实例的挂载位置 <div id ‘app’> </div> 一、创建vue实例 1.为什么要 new vue() ,直接调用vue&#xff08;&#xff09;函数可以吗&#xff1f; No&#xff0c; 因为直接调用vue()函数&#xff0c;不创建实例的话&#xff0c;会出现以下错误&#xff1…

通过 Parallels Desktop 虚拟机安装运行 macOS 15 Sequoia

在 Apple 的 WWDC 24 大会上&#xff0c;macOS Sequoia 15 成为全场热议的焦点。 作为科技爱好者和开发者&#xff0c;我们都迫不及待想要体验这些最新功能。但如果直接把整个 Mac 升级到测试版&#xff0c;可能不太现实&#xff0c;特别是当你需要保持主系统稳定的时候。 幸…

单例模式之饿汉式

文章目录 单例模式&#xff08;饿汉式&#xff09;代码静态变量创建实例代码静态代码块创建实例 单例模式&#xff08;饿汉式&#xff09; 单例模式是一种创建性的设计模式&#xff0c;主要是保证一个类只能有一个实例。全局中保证一个实例的使用。 单例模式饿汉式主要的构成…

数据库常见问题(持续更新)

数据库常见问题(持续更新) 1、数据库范式&#xff1f; 1NF&#xff1a;不可分割2NF&#xff1a;没有非主属性对候选码存在部分依赖3NF&#xff1a;没有非主属性传递依赖候选码BCNF&#xff1a;消除了主属性对对候选码的传递依赖或部分依赖 2、InnoDB事务的实现&#xff1f; …

大数据平台建设概要

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; 欢迎关注微信公众号&#xff1a;野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来&a…