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库,通过注解处理器在编译期自动生成模板代码(如getter
、setter
),无需手动编写。它的核心优势是:
- 减少模板代码,精简类定义;
- 避免修改字段后忘记更新
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:
- 打开
File → Settings → Plugins
; - 搜索“Lombok”并安装,重启IDE;
- 开启注解处理:
Settings → Build, Execution, Deployment → Compiler → Annotation Processors → 勾选Enable annotation processing
。
- 打开
- Eclipse:
- 安装Lombok插件(官网下载
lombok.jar
,双击运行并指定Eclipse安装目录); - 重启Eclipse。
- 安装Lombok插件(官网下载
二、Lombok常用注解详解
2.1 @Data:一站式生成核心方法
功能:自动生成getter
、setter
、toString()
、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
:指定方法访问权限(PUBLIC
、PROTECTED
、PACKAGE
、PRIVATE
),默认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 + ")";
}
注意:
exclude
和of
不可同时使用;- 若继承父类,可添加
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-catch
或throws
声明。
使用示例:
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 优点
- 减少模板代码:省去大量
getter
、setter
等重复代码; - 提高开发效率:新增字段时无需手动更新相关方法;
- 代码更简洁:聚焦核心业务逻辑,可读性提升。
4.2 缺点
- 强依赖插件:IDE必须安装Lombok插件,否则会报错;
- 调试困难:生成的代码在源码中不可见,调试时需查看编译后的class文件;
- 过度使用风险:滥用
@Data
可能导致类职责不清晰; - 兼容性问题:某些框架(如序列化工具)可能无法识别生成的方法。
4.3 避坑指南
- 避免在父类使用@Data:子类继承后可能导致
equals()
和hashCode()
逻辑错误; - 谨慎使用@SneakyThrows:不要在业务核心逻辑中隐藏受检异常,以免影响异常处理;
- 序列化注意:若类需要序列化(如实现
Serializable
),建议手动编写serialVersionUID
(Lombok不自动生成); - 版本兼容:确保Lombok版本与JDK版本兼容(如JDK 17需Lombok 1.18.20+);
- 代码审查:生成的代码虽不可见,但需在审查时考虑其逻辑(如
equals()
是否符合预期)。
总结
核心推荐注解:
- 实体类:
@Data
+@NoArgsConstructor
+@AllArgsConstructor
; - 服务类:
@Slf4j
+@RequiredArgsConstructor
; - 不可变对象:
@Value
; - 日志:
@Slf4j
。
若这篇内容帮到你,动动手指支持下!关注不迷路,干货持续输出!
ヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノ