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

Lombok常用注解及功能详解

Lombok常用注解及功能详解

    • 一、Lombok简介与环境配置
      • 1.1 什么是Lombok?
      • 1.2 环境配置
        • 1.2.1 Maven项目
        • 1.2.2 Gradle项目
        • 1.2.3 IDE配置(关键)
    • 二、Lombok常用注解详解
      • 2.1 @Data:一站式生成核心方法
      • 2.2 @Getter/@Setter:单独生成getter/setter
      • 2.3 @ToString:生成toString()方法
      • 2.4 @NoArgsConstructor/@AllArgsConstructor:生成构造方法
      • 2.5 @RequiredArgsConstructor:生成必需字段的构造方法
      • 2.6 @NonNull:字段非空校验
      • 2.7 @Slf4j:简化日志对象创建
      • 2.8 @Builder:实现建造者模式
      • 2.9 @Value:生成不可变类
      • 2.10 @SneakyThrows:简化异常处理
    • 三、Lombok注解组合使用场景
      • 3.1 实体类(POJO)
      • 3.2 服务类(Service)
      • 3.3 不可变DTO
    • 四、Lombok的优缺点与避坑指南
      • 4.1 优点
      • 4.2 缺点
      • 4.3 避坑指南
      • 总结

Java开发中,实体类的getter/setter、构造方法、toString()等模板代码往往占据大量篇幅,不仅编写繁琐,还会降低代码可读性,Lombok通过注解机制自动生成这些模板代码,让我们能够更专注于核心业务逻辑。

一、Lombok简介与环境配置

1.1 什么是Lombok?

Lombok是一个Java库,通过注解处理器在编译期自动生成模板代码(如gettersetter),无需手动编写。它的核心优势是:

  • 减少模板代码,精简类定义;
  • 避免修改字段后忘记更新getter/setter的问题;
  • 提高代码可读性,聚焦业务逻辑。

1.2 环境配置

1.2.1 Maven项目

pom.xml中添加依赖:

<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version><optional>true</optional> <!-- 避免传递依赖 -->
</dependency>
1.2.2 Gradle项目

build.gradle中添加:

implementation 'org.projectlombok:lombok:1.18.24'
annotationProcessor 'org.projectlombok:lombok:1.18.24'
1.2.3 IDE配置(关键)

Lombok通过编译期生成代码,IDE需安装插件才能识别生成的方法(否则会报“方法不存在”错误):

  • IntelliJ IDEA
    1. 打开File → Settings → Plugins
    2. 搜索“Lombok”并安装,重启IDE;
    3. 开启注解处理:Settings → Build, Execution, Deployment → Compiler → Annotation Processors → 勾选Enable annotation processing
  • Eclipse
    1. 安装Lombok插件(官网下载lombok.jar,双击运行并指定Eclipse安装目录);
    2. 重启Eclipse。

二、Lombok常用注解详解

2.1 @Data:一站式生成核心方法

功能:自动生成gettersettertoString()equals()hashCode()方法,以及包含所有字段的构造方法。

使用示例

import lombok.Data;@Data
public class User {private Long id;private String username;private Integer age;
}

等价于手动编写

public class User {private Long id;private String username;private Integer age;// getterpublic Long getId() { return id; }public String getUsername() { return username; }public Integer getAge() { return age; }// setterpublic void setId(Long id) { this.id = id; }public void setUsername(String username) { this.username = username; }public void setAge(Integer age) { this.age = age; }// toStringpublic String toString() { return "User(id=" + id + ", username=" + username + ", age=" + age + ")"; }// equals和hashCode(基于所有字段)public boolean equals(Object o) { /* 实现 */ }public int hashCode() { /* 实现 */ }// 全参构造方法public User(Long id, String username, Integer age) {this.id = id;this.username = username;this.age = age;}
}

注意

  • @Data不包含无参构造方法,若需要需额外添加@NoArgsConstructor
  • 适合POJO类(如实体类、DTO),不建议在复杂业务类中使用。

2.2 @Getter/@Setter:单独生成getter/setter

功能:为类中所有字段(或指定字段)生成getter/setter方法。

使用示例

import lombok.Getter;
import lombok.Setter;@Getter // 为所有字段生成getter
@Setter // 为所有字段生成setter
public class Product {private Long id;private String name;@Getter(AccessLevel.PRIVATE) // 仅为price生成private getter@Setter(AccessLevel.PROTECTED) // 仅为price生成protected setterprivate Double price;
}

关键参数

  • AccessLevel:指定方法访问权限(PUBLICPROTECTEDPACKAGEPRIVATE),默认PUBLIC

适用场景

  • 只需生成部分字段的getter/setter
  • 需要控制getter/setter的访问权限。

2.3 @ToString:生成toString()方法

功能:生成包含类名和字段的toString()方法,可指定包含/排除字段。

使用示例

import lombok.ToString;@ToString(includeFieldNames = true, // 输出字段名(默认true)exclude = "password", // 排除password字段of = {"username", "age"} // 仅包含指定字段(与exclude二选一)
)
public class User {private Long id;private String username;private Integer age;private String password;
}

生成的toString()

public String toString() {return "User(username=" + username + ", age=" + age + ")";
}

注意

  • excludeof不可同时使用;
  • 若继承父类,可添加callSuper = true包含父类的toString()结果(默认false)。

2.4 @NoArgsConstructor/@AllArgsConstructor:生成构造方法

  • @NoArgsConstructor:生成无参构造方法;
  • @AllArgsConstructor:生成包含所有字段的构造方法。

使用示例

import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;@NoArgsConstructor
@AllArgsConstructor
public class Book {private String isbn;private String title;private String author;
}

生成的构造方法

// 无参构造
public Book() {}// 全参构造
public Book(String isbn, String title, String author) {this.isbn = isbn;this.title = title;this.author = author;
}

注意

  • 若类中已有构造方法,@NoArgsConstructor会覆盖默认无参构造(若未显式定义);
  • 配合@Data使用时,需显式添加@NoArgsConstructor(因@Data不包含无参构造)。

2.5 @RequiredArgsConstructor:生成必需字段的构造方法

功能:为final或被@NonNull标注的字段生成构造方法。

使用示例

import lombok.RequiredArgsConstructor;
import lombok.NonNull;@RequiredArgsConstructor
public class Order {private final Long orderId; // final字段(必需)@NonNull private String productName; // @NonNull标注(必需)private Integer quantity; // 普通字段(非必需)
}

生成的构造方法

public Order(Long orderId, String productName) {this.orderId = orderId;if (productName == null) {throw new NullPointerException("productName is marked non-null but is null");}this.productName = productName;
}

适用场景

  • 依赖注入(如构造方法注入@Autowired);
  • 确保核心字段必须初始化。

2.6 @NonNull:字段非空校验

功能:在构造方法或setter中为字段添加非空校验,若为null则抛出NullPointerException

使用示例

import lombok.NonNull;
import lombok.Setter;public class User {private Long id;@NonNull private String username; // 非空校验@Setter@NonNull private Integer age; // setter中添加非空校验
}

生成的代码

public class User {private Long id;private String username;private Integer age;public User(String username) {if (username == null) {throw new NullPointerException("username is marked non-null but is null");}this.username = username;}public void setAge(Integer age) {if (age == null) {throw new NullPointerException("age is marked non-null but is null");}this.age = age;}
}

注意@NonNull需配合构造方法或setter使用(如与@Data@Setter等注解一起用)。

2.7 @Slf4j:简化日志对象创建

功能:自动生成日志对象(private static final Logger log = LoggerFactory.getLogger(类名.class);),支持主流日志框架(Logback、Log4j2等)。

使用示例

import lombok.extern.slf4j.Slf4j;@Slf4j // 生成log对象
public class OrderService {public void createOrder() {log.info("开始创建订单"); // 直接使用log对象try {// 业务逻辑log.debug("订单创建成功");} catch (Exception e) {log.error("订单创建失败", e); // 打印异常}}
}

等价于手动编写

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class OrderService {private static final Logger log = LoggerFactory.getLogger(OrderService.class);public void createOrder() {log.info("开始创建订单");// ...}
}

类似注解

  • @Log:对应java.util.logging.Logger
  • @Log4j:对应Log4j 1.x;
  • @Log4j2:对应Log4j 2.x。
  • 推荐使用@Slf4j(Slf4j是日志门面,可适配不同日志框架)。

2.8 @Builder:实现建造者模式

功能:为类生成建造者模式代码,支持链式调用创建对象。

使用示例

import lombok.Builder;
import lombok.ToString;@Builder
@ToString
public class User {private Long id;private String username;private Integer age;
}

使用建造者创建对象

public class Test {public static void main(String[] args) {// 链式调用设置属性User user = User.builder().id(1L).username("张三").age(20).build(); // 构建对象System.out.println(user); // 输出:User(id=1, username=张三, age=20)}
}

优势

  • 相比构造方法,无需记忆参数顺序;
  • 支持选择性设置字段(无需为可选字段创建多个构造方法)。

注意@Builder默认生成全参私有构造方法,若需公开构造方法,需配合@NoArgsConstructor@AllArgsConstructor

2.9 @Value:生成不可变类

功能:生成不可变类(类似@Data,但字段默认为final,且无setter)。

使用示例

import lombok.Value;@Value
public class ImmutableUser {Long id;String username;Integer age;
}

生成的代码特点

  • 所有字段被final修饰(不可修改);
  • 生成getter,但无setter
  • 生成全参构造方法(必须初始化所有字段);
  • 生成toString()equals()hashCode()

适用场景

  • 存储常量数据(如配置信息);
  • 线程安全的不可变对象。

2.10 @SneakyThrows:简化异常处理

功能:自动捕获受检异常(Checked Exception)并包装为运行时异常抛出,无需显式try-catchthrows声明。

使用示例

import lombok.SneakyThrows;
import java.io.FileInputStream;public class FileUtil {// 无需声明throws IOException@SneakyThrowspublic static void readFile() {FileInputStream fis = new FileInputStream("test.txt");// ...}
}

生成的代码

public class FileUtil {public static void readFile() {try {FileInputStream fis = new FileInputStream("test.txt");} catch (IOException e) {throw new RuntimeException(e); // 包装为运行时异常}}
}

注意

  • 谨慎使用,可能隐藏异常类型(调用者无法通过throws声明感知受检异常);
  • 适合简化工具类中的异常处理。

三、Lombok注解组合使用场景

3.1 实体类(POJO)

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.ToString;@Data // getter、setter、toString等
@NoArgsConstructor // 无参构造(JSON反序列化需要)
@AllArgsConstructor // 全参构造(测试用)
@ToString(exclude = "password") //  toString排除密码
public class User {private Long id;private String username;@NonNull // 非空校验private String password;private Integer age;
}

3.2 服务类(Service)

import lombok.extern.slf4j.Slf4j;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;@Service
@Slf4j // 日志
@RequiredArgsConstructor // 构造方法注入依赖
public class UserService {private final UserMapper userMapper; // final字段(构造方法注入)public User getUserById(Long id) {log.info("查询用户ID:{}", id);return userMapper.selectById(id);}
}

3.3 不可变DTO

import lombok.Value;
import lombok.Builder;@Value // 不可变类
@Builder // 支持建造者模式创建
public class UserDTO {Long id;String username;Integer age;
}

四、Lombok的优缺点与避坑指南

4.1 优点

  1. 减少模板代码:省去大量gettersetter等重复代码;
  2. 提高开发效率:新增字段时无需手动更新相关方法;
  3. 代码更简洁:聚焦核心业务逻辑,可读性提升。

4.2 缺点

  1. 强依赖插件:IDE必须安装Lombok插件,否则会报错;
  2. 调试困难:生成的代码在源码中不可见,调试时需查看编译后的class文件;
  3. 过度使用风险:滥用@Data可能导致类职责不清晰;
  4. 兼容性问题:某些框架(如序列化工具)可能无法识别生成的方法。

4.3 避坑指南

  1. 避免在父类使用@Data:子类继承后可能导致equals()hashCode()逻辑错误;
  2. 谨慎使用@SneakyThrows:不要在业务核心逻辑中隐藏受检异常,以免影响异常处理;
  3. 序列化注意:若类需要序列化(如实现Serializable),建议手动编写serialVersionUID(Lombok不自动生成);
  4. 版本兼容:确保Lombok版本与JDK版本兼容(如JDK 17需Lombok 1.18.20+);
  5. 代码审查:生成的代码虽不可见,但需在审查时考虑其逻辑(如equals()是否符合预期)。

总结

核心推荐注解:

  • 实体类:@Data + @NoArgsConstructor + @AllArgsConstructor
  • 服务类:@Slf4j + @RequiredArgsConstructor
  • 不可变对象:@Value
  • 日志:@Slf4j

若这篇内容帮到你,动动手指支持下!关注不迷路,干货持续输出!
ヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノ

http://www.lryc.cn/news/607165.html

相关文章:

  • Redis学习18-分布式锁
  • Vue 3.5 defineModel:让组件开发效率提升 10 倍
  • 暑期算法训练.12
  • 【VSCode】常用插件推荐(持续更新~)
  • 从资源闲置到弹性高吞吐,JuiceFS 如何构建 70GB/s 吞吐的缓存池?
  • C 实现难度过高的俄罗斯方块
  • 数据赋能(371)——数据挖掘——概述
  • LLM Prompt与开源模型资源(1)提示词工程介绍
  • UniApp与WebView双向通信机制及生产级实现方案全解析
  • 计数组合学7.10(舒尔函数的组合定义)
  • Golang 语言 Channel 的使用方式
  • 数据结构:链表(Linked List)
  • 如何通过黑白棋盘进行定位配准融合?(前后安装的两个相机)
  • 【Mysql】联合索引生效分析案例
  • 【科研绘图系列】R语言绘制环状分组显著性柱状堆积图
  • 鹧鸪云:16步精控工商业光伏全流程
  • java8学习笔记-Stream流
  • GitPython08-源码解读
  • 网络编程接口bind学习
  • MySQL时间处理完全指南:从存储到查询优化
  • Java向量化
  • 如何处理Y2K38问题
  • 利用 AI 在 iPhone 上实现 App 文本情绪价值评估(上)
  • 【AI应用】 能源保供战:AI大模型如何守护万家灯火?
  • TGD第十篇:当神经网络遇到TGD特征
  • Qt 开发自动化测试框架搭建
  • 【华为机试】34. 在排序数组中查找元素的第一个和最后一个位置
  • OSPF综合大实验
  • python学智能算法(三十))|SVM-KKT条件的数学理解
  • Git基础命令大全