1. 程式人生 > >Lombok 使用詳解,簡化Java程式設計

Lombok 使用詳解,簡化Java程式設計

前言

在 Java 應用程式中存在許多重複相似的、生成之後幾乎不對其做更改的程式碼,但是我們還不得不花費很多精力編寫它們來滿足 Java 的編譯需求

比如,在 Java 應用程式開發中,我們幾乎要為所有 Bean 的成員變數新增 get() ,set() 等方法,這些相對固定但又不得不編寫的程式碼浪費程式設計師很多精力,同時讓類內容看著更雜亂,我們希望將有限的精力關注在更重要的地方。

Lombok 已經誕生很久了,甚至在 Spring Boot Initalizr 中都已加入了 Lombok 選項,

這裡我們將 Lombok 做一下詳細說明:

Lombok

官網的介紹:Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java. Never write another getter or equals method again. Early access to future java features such as val, and much more.

直白的說: Lombok 是一種 Java™ 實用工具,可用來幫助開發人員消除 Java 的冗長,尤其是對於簡單的 Java 物件(POJO)。它通過註解實現這一目的,且看:

Bean 的對比

傳統的 POJO 類是這樣的

通過Lombok改造後的 POJO 類是這樣的

一眼可以觀察出來我們在編寫 Employee 這個類的時候通過 @Data 註解就已經實現了所有成員變數的 get()set() 方法等,同時 Employee 類看起來更加清晰簡潔。Lombok 的神奇之處不止這些,豐富的註解滿足了我們開發的多數需求。

Lombok的安裝

檢視下圖,@Data的實現,我們發現這個註解是應用在編譯階段的

這和我們大多數使用的註解,如 Spring 的註解(在執行時,通過反射來實現業務邏輯)是有很大差別的,如Spring 的@RestController 註解

一個更直接的體現就是,普通的包在引用之後一般的 IDE 都能夠自動識別語法,但是 Lombok 的這些註解,一般的 IDE 都無法自動識別,因此如果要使用 Lombok 的話還需要配合安裝相應的外掛來支援 IDE 的編譯,防止IDE 的自動檢查報錯,下面以 IntelliJ IDEA 舉例安裝外掛。

在Repositories中搜索Lombok,安裝後重啟IDE即可

在Maven或Gradle工程中新增依賴

至此我們就可以應用 Lombok 提供的註解幹些事情了。

Lombok註解詳解

Lombok官網提供了許多註解,但是 “勁酒雖好,可不要貪杯哦”,接下來逐一講解官網推薦使用的註解(有些註解和原有Java編寫方式沒太大差別的也沒有在此處列舉,如@ Synchronized等)

@Getter和@Setter

該註解可應用在類或成員變數之上,和我們預想的一樣,@Getter@Setter 就是為成員變數自動生成 get 和 set 方法,預設生成訪問許可權為 public 方法,當然我們也可以指定訪問許可權 protected 等,如下圖:

成員變數name指定生成set方法,並且訪問許可權為protected;boolean型別的成員變數 female 只生成get方法,並修改方法名稱為 isFemale()。當把該註解應用在類上,預設為所有非靜態成員變數生成 get 和 set 方法,也可以通過 AccessLevel.NONE 手動禁止生成get或set方法,如下圖:

@ToString

該註解需應用在類上,為我們生成 Object 的 toString 方法,而該註解裡面的幾個屬效能更加豐富我們想要的內容, exclude 屬性禁止在 toString 方法中使用某欄位,而of屬性可以指定需要使用的欄位,如下圖:

檢視編譯後的Employee.class得到我們預期的結果,如下圖

@EqualsAndHashCode

該註解需應用在類上,使用該註解,lombok會為我們生成 equals(Object other) 和 hashcode() 方法,包括所有非靜態屬性和非transient的屬性,同樣該註解也可以通過 exclude 屬性排除某些欄位,of 屬性指定某些欄位,也可以通過 callSuper 屬性在重寫的方法中使用父類的欄位,這樣我們可以更靈活的定義bean的比對,如下圖:

檢視編譯後的Employee.class檔案,如下圖:

@NonNull

該註解需應用在方法或構造器的引數上或屬性上,用來判斷引數的合法性,預設丟擲 NullPointerException 異常

檢視NonNullExample.class檔案,會為我們丟擲空指標異常,如下圖:

當然我們可以通過指定異常型別丟擲其他異常,lombok.nonNull.exceptionType = [NullPointerException | IllegalArgumentException] , 為實現此功能我們需要在專案的根目錄新建lombok.config檔案:

重新編譯NonNullExample類,已經為我們丟擲非法引數異常:

@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor

以上三個註解分別為我們生成無參構造器,指定引數構造器和包含所有引數的構造器,預設情況下,@RequiredArgsConstructor, @AllArgsConstructor 生成的構造器會對所有標記 @NonNull 的屬性做非空校驗。

無參構造器很好理解,我們主要看看後兩種,先看 @RequiredArgsConstructor

從上圖中我們可以看出, @RequiredArgsConstructor 註解生成有引數構造器時只會包含有 final 和 @NonNull 標識的 field,同時我們可以指定 staticName 通過生成靜態方法來構造物件

檢視Employee.class檔案

當我們把 staticName 屬性去掉我們來看遍以後的檔案:

相信你已經注意到細節

@AllArgsConstructor 就更簡單了,請大家自行檢視吧

@Data

介紹了以上的註解,再來介紹 @Data 就非常容易懂了,@Data 註解應用在類上,是@ToString, @EqualsAndHashCode, @Getter / @Setter@RequiredArgsConstructor合力的體現,如下圖:

@Builder

函數語言程式設計或者說流式的操作越來越流行,應用在大多數語言中,讓程式更具更簡介,可讀性更高,編寫更連貫,@Builder就帶來了這個功能,生成一系列的builder API,該註解也需要應用在類上,看下面的例子就會更加清晰明瞭。

編譯後的Employee.class檔案如下:

媽媽再也不用擔心我 set 值那麼麻煩了,流式操作搞定:

@Log

該註解需要應用到類上,在編寫服務層,需要新增一些日誌,以便定位問題,我們通常會定義一個靜態常量Logger,然後應用到我們想日誌的地方,現在一個註解就可以實現:

檢視class檔案,和我們預想的一樣:

Log有很多變種,CommonLog,Log4j,Log4j2,Slf4j等,lombok依舊良好的通過變種註解做良好的支援:

我實際使用的是 @Slf4j 註解

val

熟悉 Javascript 的同學都知道,var 可以定義任何型別的變數,而在 java 的實現中我們需要指定具體變數的型別,而 val 讓我們擺脫指定,編譯之後就精準匹配上型別,預設是 final 型別,就像 java8 的函式式表示式,()->System.out.println(“hello lombok”); 就可以解析到Runnable函式式介面。


檢視解析後的class檔案:

@Cleanup

當我們對流進行操作,我們通常需要呼叫 close 方法來關閉或結束某資源,而 @Cleanup 註解可以幫助我們呼叫 close 方法,並且放到 try/finally 處理塊中,如下圖:

編譯後的class檔案如下,我們發現被try/finally包圍處理,並呼叫了流的close方法

其實在 JDK1.7 之後就有了 try-with-resource,不用我們顯式的關閉流,這個請大家自行看吧

總結

Lombok的基本操作流程是這樣的:

  1. 定義編譯期的註解
  2. 利用JSR269 api(Pluggable Annotation Processing API )建立編譯期的註解處理器
  3. 利用tools.jar的javac api處理AST(抽象語法樹)
  4. 將功能註冊進jar包

Lombok 當然還有很多註解,我推薦使用以上就足夠了,這個工具是帶來便利的,而不能被其捆綁,“弱水三千只取一瓢飲,程式碼千萬需抓重點看”,Lombok 能讓我更加專注有效程式碼排除意義微小的障眼程式碼(get,set等),另外Lombok生成的程式碼還能像使用工具類一樣方便(@Builder)。

更多內容請檢視官網:https://www.projectlombok.org/


靈魂追問

  1. 為什麼只有一個整體 @EqualsAndHashCode 註解?而不是 @Equals@HashCode?這涉及到一個規範哦
  2. 如果把三種構造器方式同時應用又加上了 @Builder 註解,會發生什麼?
  3. 你的燈還亮著嗎?

  1. Java升級那麼快,多個版本如何靈活切換和管理?
  2. 手把手教你定製標準 Spring Boot starter
  3. EasyExcel輕鬆靈活讀取Excel內容

歡迎持續關注公眾號:「日拱一兵」

  • 前沿 Java 技術乾貨分享
  • 高效工具彙總 | 回覆「工具」
  • 面試問題分析與解答
  • 技術資料領取 | 回覆「資料」

以讀偵探小說思維輕鬆趣味學習 Java 技術棧相關知識,本著將複雜問題簡單化,抽象問題具體化和圖形化原則逐步分解技術問題,技術持續更新,請持續關注......


相關推薦

Lombok 使用簡化Java程式設計

前言 在 Java 應用程式中存在許多重複相似的、生成之後幾乎不對其做更改的程式碼,但是我們還不得不花費很多精力編寫它們來滿足 Java 的編譯需求 比如,在 Java 應用程式開發中,我們幾乎要為所有 Bean 的成員變數新增 get() ,set() 等方法,這些相對固定但又不得不編寫的程式碼浪費程式設計

對稱加密以及JAVA簡單實現

turn bsp 十進制 stat mage 需要 對稱密鑰 else ges (原) 常用的加密有3種 1、正向加密,如MD5,加密後密文固定,目前還沒辦法破解,但是可以能過數據庫撞庫有一定概率找到,不過現在一般用這種方式加密都會加上鹽值。 2、對稱加密,通過一個固定

druid連線池 使用java+mysql為例

druid資料來源連線池配置詳解,基於druid.jar。以java+mysq為例,配置是如下: 相關屬性: 配置 預設值 說明 name   配置這個屬性的意義在於,如

重走JAVA程式設計路:Js中self,top,parent,opener傻傻分不清楚

昨天專案遇到的問題:取上級window視窗物件時,傻傻分不清楚!你能分清楚嗎? 當我們在瀏覽器中開啟一個網頁時,瀏覽器都會建立一個視窗物件,這個視窗就是一個window物件。也就是Js生存依附的全域性環境物件和全域性作用域物件。 1.Self 指當前視窗頁面,就是wind

Java BigDecimal提供了豐富的四舍五入規則

字節 equals mat hashcode 字符 plain move man gnu java.math.BigDecimal類提供用於算術,刻度操作,舍入,比較,哈希算法和格式轉換操作。 toString()方法提供BigDecimal的規範表示。它使用戶可以完全控制

Java BigDecimal提供了豐富的四捨五入規則

原文地址:https://www.cnblogs.com/qynprime/p/8028397.html java.math.BigDecimal類提供用於算術,刻度操作,舍入,比較,雜湊演算法和格式轉換操作。 toString()方法提供BigDecimal的規範表示。它使使用者可以完全控

Java中的集合結合 ArrayList、HashSet 的區別以及HashCode的作用。

Java中的集合:      (1)Collection                           List(有序,可重複)             ArrayList         

關於阿里雲oss物件儲存含sts授權java程式碼

  我在專案上需要使用一個阿里雲的oss來進行圖片的上傳。看過oss的介紹和api之後,先寫一個簡單的程式碼。 maven地址引入jar  <dependency>          

歸併排序Java版描述。

為了簡單起見,使用int型別陣列講述歸併演算法,後面擴充套件到其他型別的排序。 目錄 1.1 用具體例子說明 十人排序問題。 將十人均分為兩隊 五人分為三人,二人兩隊 對於三人的隊伍,再次分成兩人和一人的隊伍 對於兩

Java中的內部類為什麼需要內部類?

內部類的共性   內部類分為: 成員內部類、靜態巢狀類、方法內部類、匿名內部類。      (1)、內部類仍然是一個獨立的類,在編譯之後內部類會被編譯成獨立的.class檔案,但是前面冠以外部類的類

Maven依賴中的scope在eclipse裡面用maven install可以程式設計成功到伺服器上用命令執行報VM crash錯誤

 Maven依賴中的scope詳解 專案中用了<scope>test</scope>在eclipse裡面用maven install可以編譯成功,到伺服器上用命令執行報VM crash錯誤,原因是test程式碼提交上去了,但沒有對應的junit包導致的 解決辦法:1.伺服器上編譯的時

java中ArrayList用法基本用法(含增刪改查)

1、什麼是ArrayList ArrayList就是動態陣列,它提供了①動態的增加和減少元素 ②實現了ICollection和IList介面 ③靈活的設定陣列的大小ArrayList是一個其容量能夠動態增長的動態陣列。它繼承了AbstractList,實現了List、Rand

Java執行緒池看這篇就夠了!

構造一個執行緒池為什麼需要幾個引數?如果避免執行緒池出現OOM?Runnable和Callable的區別是什麼?本文將對這些問題一一解答,同時還將給出使用執行緒池的常見場景和程式碼片段。 基礎知識 Executors建立執行緒池 Java中建立執行緒池很簡單,只需要呼叫Execu

【本人禿頂程式設計師】Java執行緒池看這篇就夠了!

←←←←←←←←←←←← 快!點關注!!! 構造一個執行緒池為什麼需要幾個引數?如果避免執行緒池出現OOM?Runnable和Callable的區別是什麼?本文將對這些問題一一解答,同時還將給出使用執行緒池的常見場景和程式碼片段。 基礎知識 Executors建立執行緒池 J

Java中的Stringjavap&cfr.jar反編譯javap反編譯後二進位制指令程式碼Java8常量池的位置

一個例子   public class TestString{ public static void main(String[] args){ String a = "a"; String b = a+"b";

java獲取硬碟ID以及MAC地址等唯一標識碼(測試通過)

為了達到軟體註冊,或者說軟體和電腦繫結的目的,需要將電腦上的固定編號進行一系列的演算法計算,並生成唯一和軟體匹配的號碼。那麼使用java如何達到這個目的呢?通常做法都是通過java的Runtime來完成,通過 process的輸入流,進行獲取相關的資訊。下面列舉具體的例子: 

Java網路程式設計和NIO開篇:Java網路程式設計基礎

老曹眼中的網路程式設計基礎 轉自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我們是幸運的,因為我們擁有網路。網路是一個神奇的東西,它改變了你和我的生活方式,改變了整個世界。 然而,網路的無標度和

第四天:JAVA中的迴圈語句和常用例子

1:switch語句(掌握)(1)格式:switch(表示式) {case 值1:語句體1;break;case 值2:語句體2;break;...default:語句體n+1;break;}格式解釋說明:switch:說明這是switch語句。表示式:可以是byte,short,int,charJDK5以後

java動態代理並用動態代理和註解實現日誌記錄功能

動態代理的概念       動態代理是程式在執行過程中自動建立一個代理物件來代替被代理的物件去執行相應的操作,例如, 我們有一個已經投入執行的專案中有一個使用者DAO類UserDao用來對User物件進行資料庫的增刪改查操作,但是有一天,要求在對使用者的增刪改查操作時記錄相

Java: synchronized靜態同步方法普通同步方法同步程式碼塊

對程式碼進行同步控制我們可以選擇同步方法,也可以選擇同步塊,這兩種方式各有優缺點,至於具體選擇什麼方式,就見仁見智了,同步塊不僅可以更加精確的控制物件鎖,也就是控制鎖的作用域,何謂鎖的作用域?鎖的作用域就是從鎖被獲取到其被釋放的時間。而且可以選擇要獲取哪個物