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
。
若這篇內容幫到你,動動手指支持下!關注不迷路,干貨持續輸出!
ヾ(′? ˋ)ノヾ(′? ˋ)ノヾ(′? ˋ)ノヾ(′? ˋ)ノヾ(′? ˋ)ノ