@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领…

运维系列.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; 输入&…

谷粒商城学习笔记-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…

STM32对数码管显示的控制

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

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

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

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

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

Unity--射线检测--RayCast

Unity–射线检测–RayCast 1.射线检测的含义 射线检测,根据名称而言,使用一条射线来检测是击中了某个物体/多个物体 射线检测的包含两个部分: 射线和检测 2.射线检测可以用在哪些地方 射击游戏&#xff1a; 玩家的瞄准和射击&#xff1a;检测玩家视线是否与敌人或其他目标…

阶段三:项目开发---大数据开发运行环境搭建:任务5:安装配置Kafka

任务描述 知识点&#xff1a;安装配置Kafka 重 点&#xff1a; 安装配置Kafka 难 点&#xff1a;无 内 容&#xff1a; Kafka是由Apache软件基金会开发的一个开源流处理平台&#xff0c;由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;…

用起来超爽的4个宝藏软件工具

记得带 “记得带”是一款专为繁忙的都市人设计的生活服务软件&#xff0c;旨在帮助用户轻松管理日常生活中的各种事务。该应用程序集成了多种实用功能&#xff0c;包括购物清单、待办事项、日程安排和健康追踪等。它还具有智能提醒功能&#xff0c;可以根据用户的日常习惯和偏好…

14-41 剑和诗人15 - RLAIF 大模型语言强化培训

​​​​​​ 介绍 大型语言模型 (LLM) 在自然语言理解和生成方面表现出了巨大的能力。然而&#xff0c;这些模型仍然存在严重的缺陷&#xff0c;例如输出不可靠、推理能力有限以及缺乏一致的个性或价值观一致性。 为了解决这些限制&#xff0c;研究人员采用了一种名为“人工…

easily-openJCL 让 Java 与显卡之间的计算变的更加容易!

easily-openJCL 让 Java 与显卡之间的计算变的更加容易&#xff01; 开源技术栏 本文介绍了关于在 Java 中 easily-openJCL 的基本使用&#xff01;&#xff01;&#xff01; 目录 文章目录 easily-openJCL 让 Java 与显卡之间的计算变的更加容易&#xff01;目录 easily-op…

算法学习笔记(8)-动态规划基础篇

目录 基础内容&#xff1a; 动态规划&#xff1a; 动态规划理解的问题引入&#xff1a; 解析&#xff1a;&#xff08;暴力回溯&#xff09; 代码示例&#xff1a; 暴力搜索&#xff1a; Dfs代码示例&#xff1a;&#xff08;搜索&#xff09; 暴力递归产生的递归树&…

matlab仿真 信道(上)

&#xff08;内容源自详解MATLAB&#xff0f;SIMULINK 通信系统建模与仿真 刘学勇编著第四章内容&#xff0c;有兴趣的读者请阅读原书&#xff09; 1.加性高斯白噪声信道&#xff08;AWGN &#xff09; clear all t0:0.001:10; xsin(2*pi*t);%原始信号 snr20;%设定加性白噪…

CSS技巧:清除浏览器默认样式,让你的页面全由你做主!

莫名其妙的的问题哪里来? 你有没有过写了半天样式&#xff0c;却发现总有些与你想要的效果不同的地方&#xff1a;input带个黑框框&#xff0c;list 的小圈圈&#xff0c;锚点的文字颜色&#xff0c;莫名其妙多出来的一两个像素的距离。。 回到20年前&#xff0c;我刚刚接触…

HBuilder X 小白日记03-用css制作简单的交互动画

:hover选择器&#xff0c;用于选择鼠标指针浮动在上面的元素。 :hover选择器可用于所有元素&#xff0c;不只是链接 :link选择器 设置指向未被访问页面的链接的样式 :visited选择器 用于设置指向已被访问的页面的链接 :active选择器 用于活动链接

DBA 数据库管理

数据库&#xff1a;存储数据的仓库 数据库服务软件&#xff1a; 关系型数据库&#xff1a; 存在硬盘 &#xff0c;制作表格的 数据库的参数 [rootmysql50 ~]# cat /etc/my.cnf.d/mysql-server.cnf 主配置文件 [mysqld] datadir/var/lib/mysql 存放数据库目录…