【譯】利用Lombok消除重複代碼

當你在寫Getter和Setter時,一定無數次的想過,爲什麼會有POJO這麼爛的東西。你不是一個人!(不是罵人…)無數的開發人員花費了大量的時間來寫這種樣板代碼,而他們本來可以利用這些時間做出更有價值的輸出。

從我開始寫Java以來,已經寫了幾千行代碼了,其中大概50%都是樣板代碼,在轉型之前,我就這麼一直毫無怨言的寫着。而最近兩年,我不再Java了,轉而開始寫一些Python,Go和JavaScript的代碼。這時我才感覺到Java中的重複的樣板代碼是多麼令人沮喪。

值得慶幸的是,現在的IDE爲我們提供了自動生成這些代碼的功能。但是我仍然需要按快捷鍵或者點鼠標來操作,這是非常影響我的編碼思路的。

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

上面這段話摘自Lombok的首頁。這是一個每個人都需要使用的庫,簡直是一種仙丹!開個玩笑。Java是一門很棒的語言,但是它的冗長經常會令人感到苦惱。

Lombok到底有多香呢?我總結了以下幾點:

  1. Getter和Setter註解會自動生成getter、setter方法
  2. NoArgsConstructor和AllArgConstructor可以幫助你快速生成構造函數
  3. ToString會使POJO打印更加友好的日誌
  4. Data會讓你的POJO成爲一個完全符合規範的POJO
  5. SneakyThrows可以偷偷拋出檢查異常,而不需要再寫throws子句

想了解更多Lombok特性的話,可以自行前往https://projectlombok.org/features/all查看。

Lombok是如何工作的?

Lombok是在Java註解處理器和幾個編譯時註解的幫助下工作的,它將注入額外的Java字節碼來幫助我們處理重複的代碼。你可以查看它生成的Java代碼,這一過程被幽默的稱爲“Delombokisation”。

我應該如何開始使用?

Lombok引入了一個額外的編譯時依賴。

如果你使用vanilla javac進行編譯,你需要指定lombok.jar作爲註解處理器:javac -cp lombok.jar MyCode.java

如果你使用的是maven,那麼需要在pom.xml中插入以下代碼來保證你的代碼可以使用Lombok。

<dependencies>
	<dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
		<version>1.18.4</version>
		<scope>provided</scope>
	</dependency>
</dependencies>

如果你使用的是Gradle,那麼你需要使用Gradle Lombok插件

plugins {
    id 'io.franzbecker.gradle-lombok' version '1.14'
    id 'java'
}

設置你的IDE

從你開始使用Java起,你應該就開始使用一個智能的IDE來自動編譯或給你的代碼提供一些建議。爲了將Lombok集成進IDE,你需要告訴Lombok io來安裝合適的鉤子。

獲取Lombok的jar包後,執行java -jar lombok.jar來完成所有的設置。

IntelliJ IDEA和Visual Studio用戶需要一個單獨的Lombok插件,你可以選擇從插件庫中安裝。

代碼拿來!

talk is cheap, show me your code.程序員就應該拿代碼說話。下面我們就來看一個完整的例子。

Getters和Setters

爲被註解的自動生成getXXX和setXXX方法。

import lombok.Getter;
import lombok.Setter;

class UptimeResponse {
    // GetXXX and SetXXX are automatically generated
    @Getter @Setter private long uptime;
    @Getter @Setter private long currentTime;
    @Getter @Setter private String status;
    UptimeResponse() {
        this.uptime = ManagementFactory
                          .getRuntimeMXBean().getUptime();
        this.currentTime = System.currentTimeMillis();
        this.status = "OK";
    }
}
// So this works automagically
UptimeResponse res = new UptimeResponse();
res.setStatus("FAIL");
System.out.println(res.getUptime());

Constructors

可以自動創建默認的POJO構造函數,它將字段初始化爲默認值。

  1. NoArgConstructor創建一個無參構造函數,所有的字段都會初始化爲默認值
  2. AllArgsConstructor創建一個全參數構造函數,每個字段都會初始化爲指定值
  3. RequiredArgsConstructor創建一個構造函數,參數包括所有final字段和標記爲NotNull的字段
import lombok.*

@AllArgsConstructor
class Document {
    @Getter @Setter private String title;
    @Getter @Setter private String content;
    // ...
}
// This works automagically
Document d = new Document("Hello World", "Message Body");
d.getTitle();   // Hello World
d.getContent(); // Message Body

Equals and hash codes

Lombok可以生成的樣板代碼是包含局部變量的equals方法和hashcode方法。你可以手動排除一些字段。

import lombok.*;

@RequiredArgsConstructor
@EqualsAndHashCode
class User {
    @Getter
    private final String username;
    @EqualsAndHashCode.Exclude
    @Getter
    @Setter
    private String lastAction;  // not required for equality checks
}
// This works automagically
User u1 = new User("amitosh");
u1.setLastAction("Hello");
User u2 = new User("amitosh");
u2.setLastAction("Compile");
u1.equals(u2) // Gives true

To String

Lombok的ToString註解自動生成toString方法,其中包含類封裝的全部字段。這是用於生成調試表示的快速方法。

import lombok.ToString;
import lombok.Getter;
import lombok.Setter;

@ToString
class Entry {
    @Getter @Setter private String id;
    @Getter @Setter private String target;
}
// This works automagically
Entry e = new Entry();
// ...
System.out.println(e);  // Nice output with values of id and target

Data classes

這個註解用於生成符合規範的完整POJO。它是ToString、EqualsAndHashCode以及所有非final字段的Getter和Setter的集合體。

import lombok.Data;

@Data
class Message {
    private String sender;
    private String content;
}
// This works automagically
Message m = new Message("amitosh", "Hello World");
m.setSender("agathver");
m.getContent();  // Hello World
m.toString();    // ...

SneakyThrows

Java是一門靜態檢查語言,但有時檢查會比較多餘。例如有時我們不關心異常,或者確定代碼中不會出現異常,所以就不想去寫捕獲和處理異常的代碼。這時SneakyThrows註解可以幫助我們一起騙過編譯器。

但要注意不能濫用這個註解。

import lombok.SneakyThrows;
 
public class SneakyThrowsExample {
   @SneakyThrows(UnsupportedEncodingException.class)
   public String utf8ToString(byte[] bytes) {
       // This exception is never generated as UTF-8 is guaranteed
       // to be supported by the JVM
       return new String(bytes, "UTF-8");
   }
}

Delomboking

不是所有的工具都支持Lombok的,最著名的是JavaDoc工具。你需要有一箇中間態的代碼來使文檔正確表示。此外,有時候你可能會想看看Lombok生成的代碼到底是什麼樣的。幸好Lombok提供了“delomboking”,用來將Lombok轉換成Java源代碼。

要轉換一個文件夾下的全部代碼,可以使用以下命令:

java -jar lombok.jar delombok src -d src-delomboked

maven和gradle插件也包含了delomboking任務,在你需要的時候可以使用。

Lombok是一個提高你的Java生產力的工具。我無法想象沒有它時應該怎麼寫Java程序。真心希望你在讀完本文以後能夠認識到它的強大!

原文地址

https://medium.com/@agathver/banish-repetitive-java-code-with-lombok-f9b97d0d4137

譯者點評

Lombok是一款非常好用的工具,它可以幫助我們快速構建POJO類。但是如果直接使用@Data註解時,會破壞類的封裝特性。這點不符合面向對象編程的思想,但工作中會使用一些序列化工具,這些工具要求所有字段都要有setter方法。爲了編碼的方便,可能使用@Data方法是一個好的選擇。

發佈了141 篇原創文章 · 獲贊 375 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章