欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java開發(fā)之Lombok指南

 更新時(shí)間:2019年06月04日 09:01:10   作者:聞人的技術(shù)博客  
Lombok是一款Java開發(fā)插件,使得Java開發(fā)者可以通過其定義的一些注解來消除業(yè)務(wù)工程中冗長和繁瑣的代碼,它能夠在編譯源代碼期間自動(dòng)幫我們生成這些方法,并沒有如反射那樣降低程序的性能。下面我們來詳細(xì)了解一下吧

1. 前言

在目前眾多編程語言中,Java 語言的表現(xiàn)還是搶眼,不論是企業(yè)級(jí)服務(wù)端開發(fā),還是 Andorid 客戶端開發(fā),都是作為開發(fā)語言的首選,甚至在大數(shù)據(jù)開發(fā)領(lǐng)域,Java 語言也能占有一席之地,如 Hadoop,Spark,F(xiàn)link 大數(shù)據(jù)等。而作為已經(jīng)誕生 24 年的 Java 相比其他語言來說,編寫起來略顯得冗長和復(fù)雜,而為了能極大提升 Java 開發(fā)的效率和代碼簡潔性,一個(gè) Java 庫 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, with one annotation your class has a fully featured builder, Automate your logging variables, and much more.

從上面的說明里我們可以初步認(rèn)識(shí)一下 Lombok,一個(gè)作用于編輯器和構(gòu)建工具的 Java 庫,可以對(duì)編寫的 Java 代碼進(jìn)行增強(qiáng),比如說不用再寫實(shí)體類的 getter 方法,equals 方法而是自動(dòng)生成,自動(dòng)生成日志輸出變量等等,減少重復(fù)模板的代碼。

大概知道了 Lombok 框架提供的功能后,接下來我們就真正使用一下 Lombok 提供的注解,看它是如何幫助我們提高書寫 Java 代碼的簡潔性和效率的。

本文主要內(nèi)容涉及如下:

  • Lombok 插件安裝
  • Lombok 常用注解使用

示例項(xiàng)目:github.com/wrcj12138aa…

  • lombok-actions:

環(huán)境支持:

  • JDK 8
  • SpringBoot 2.1.4
  • Maven 3.6.0

2. 正文

2.1 安裝 Lombok

使用 Lombok 之前我們先要在所使用的 IDE 中進(jìn)行集成安裝,這里以 IDEA 為例,安裝步驟十分簡單:

前往 File -> Settings -> Plugin -> Marketplace ,搜索 Lombok

選擇搜索結(jié)果 Lombok ,點(diǎn)擊 Install 安裝。

安裝完成后重啟即可。

基于 Eclipse 的 Lombok 插件安裝方法這里就不詳細(xì)描述了,官方也給了對(duì)應(yīng)的文檔說明:projectlombok.org/setup/eclip…

在 IDE 安裝了 Lombok 插件后,我們就可以在 pom.xml 文件中添加 Lombok 的依賴進(jìn)行使用了。

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

注意:pom 依賴設(shè)置 scope 為 provided,是為了讓 Lombok 庫不被打包進(jìn)程序。

2.2 @Getter/@Setter

通常我們編寫實(shí)體類無論多少個(gè)字段,都要為其提供 getter 和 setter 方法,如下面的示例類 User.java

我們常會(huì)遇到這種情況:某個(gè)實(shí)體類新增和修改某個(gè)字段,我們都需要單獨(dú)處理調(diào)整,十分麻煩并且重復(fù)。

這時(shí)候如果我們使用 Lombok 提供 @Getter/@Setter 注解就能幫我們省去 getter 和 setter 方法的維護(hù),由 Lombok 對(duì) User 類自動(dòng)生成 getter 和 setter 方法,兩者最終的字節(jié)碼時(shí)一樣的,而我們現(xiàn)在在 User.java 上編寫的代碼僅僅 7 行即可:

@Getter
@Setter
public class User {
private Integer id;
private String username;
private String password;
}

然后用測(cè)試類 UserTests.java 測(cè)試結(jié)果如下:

public class UserTests {
@Test
public void test() {
User user = new User();
user.setUsername("one");
user.setPassword("zxc123");
Assert.assertEquals(user.getUsername(), "one");
Assert.assertEquals(user.getPassword(), "zxc123");
}
}

@Getter/@Setter 注解不僅可以使用在類上,還可以使用在字段上,這樣就是表示針對(duì)該字段自動(dòng)生成 getter /setter 方法。

@Getter
@Setter
private String password;

這里該注解使用在類上,還是在字段上的區(qū)別就是,如果注解使用在類上,只針對(duì)這個(gè)類的非靜態(tài)字段有效。

需要注意的一點(diǎn)是:如果 @Getter 注解修飾了 boolean 類型的變量,其生成的 getter 方法簽名是 isXXX 形式,而不是 getXXX形式。

除此之外,@Getter/@Setter 還提供訪問權(quán)限控制的屬性 lombok.AccessLevel value(), 默認(rèn)為 PUBLIC,而其他選值都是枚舉類型:MODULE, PROTECTED, PACKAGE, PRIVATE

2.3 @NonNull

顧名思義,@NonNull 用于標(biāo)記類中不能允許為 null 的字段或者參數(shù)上,任何使用該字段的地方都生成空指針判斷代碼,若@NonNull 標(biāo)記的變量為 null,拋出 NullPointException (NPE) 異常。比如下面示例代碼:

public class User {
private Integer id;
private String username;
private String password;
public User(Integer id, @NonNull String username, @NonNull String password) {
this.id = id;
this.username = username;
this.password = password;
}
}

使用了 @NonNull 注解之后我們可以獲取到反編譯之后的字節(jié)碼信息如下,這就是 Lombok 給我們生成的最終的代碼:

public class User {
private Integer id;
private String username;
private String password;
public User(Integer id, @NonNull String username, @NonNull String password) {
if (username == null) {
throw new NullPointerException("username is marked non-null but is null");
} else if (password == null) {
throw new NullPointerException("password is marked non-null but is null");
} else {
this.id = id;
this.username = username;
this.password = password;
}
}
}

2.4 構(gòu)造器注解

再來看下平時(shí)經(jīng)常會(huì)遇見的場(chǎng)景,為實(shí)體類編寫構(gòu)造器方法,Lombok 提供了三個(gè)不同構(gòu)造器注解 @NoArgsConstructor / @AllArgsConstructor / @RequiredArgsConstructor 分別對(duì)用不同構(gòu)造器方法處理方式,接下來就一一描述。

  • @NoArgsConstructor 為實(shí)體類生成無參的構(gòu)造器方法
  • @AllArgsConstructor 為實(shí)體類生成除了static修飾的字段之外帶有各參數(shù)的構(gòu)造器方法。
  • @RequiredArgsConstructor 為實(shí)體類生成指定字段的構(gòu)造器方法,而這些字段需要被 final,或者 @NonNull 修飾。
```java
@RequiredArgsConstructor
public class User3 {
private Integer id;
private final String username;
@NonNull
private String password;
}
```

編譯成功后使用構(gòu)造器方法時(shí)就是這樣的效果:User3 user3 = new User3("user3", "zxc123");

2.5 @ToString

@ToString 會(huì)給類自動(dòng)生成易閱讀的 toString 方法,帶上有所非靜態(tài)字段的屬性名稱和值,這樣就十分便于我們?nèi)粘i_發(fā)時(shí)進(jìn)行的打印操作。

@Getter
@Setter
@AllArgsConstructor
@ToString
public class User2 {
private Integer id;
private String username;
private String password;
}

最終編譯成字節(jié)碼,反編譯結(jié)果如下:

public class User2 {
private Integer id;
private String username;
private String password;
// 省去 setter/getter
public String toString() {
return "User2(id=" + this.getId() + ", username=" + this.getUsername() + ", password=" + this.getPassword() + ")";
}
}

另外,注解 @ToString 還支持設(shè)置指定哪些字段的日志化輸出,哪些不需要出現(xiàn)在 toString 方法中。使用屬性 @ToString.Exclude排除不需要在 toString 中出現(xiàn)的字段,使用 @ToString.Include標(biāo)記需要出現(xiàn)在 toString 中的字段,具體用法可參見示例:

@Getter
@Setter
@AllArgsConstructor
@ToString
public class User2 {
@ToString.Exclude
private Integer id;
@ToString.Include
private String username;
@ToString.Include
private String password;
}


打印 User2 對(duì)象的日志效果就是:User2(username=user2, password=zcx123)。

2.6 @EqualsAndHashCode

@EqualsAndHashCode 注解就是用于根據(jù)類所擁有的非靜態(tài)字段自動(dòng)重寫 equals 方法和 hashCode 方法,方便我們用于對(duì)象間的比較。類似 @ToString,@EqualsAndHashCode 還可以使用需要作為比較的字段和排除不需要比較的字段,具體用法可以看如下示例:

@Getter
@Setter
@AllArgsConstructor
@ToString
@EqualsAndHashCode
public class User4 {
@EqualsAndHashCode.Exclude
private Integer id;
@EqualsAndHashCode.Include
private String username;
@EqualsAndHashCode.Exclude
private String password;
}


寫完實(shí)體類代碼,我們編寫測(cè)試方法試下效果:

@Test
public void testEqual() {
User4 user4 = new User4(1, "user4", "zxc");
User4 user4_2 = new User4(1, "user4", "123");
Assert.assertEquals(user4, user4_2); // ture
}

2.7 @Data/@Value

@Data/@Value 注解,提供了更綜合的生成代碼功能,等價(jià)于下面幾個(gè)注解

  • @Getter
  • @Setter
  • @RequiredArgsConstructor
  • @ToString
  • @EqualsAndHashCode

兩個(gè)注解都只能使用在類上,與 @Data 不同, @Value 用來修飾不可變的類上。一般實(shí)體類沒有特別的限制的話,通??梢灾苯邮褂?@Data 注解修飾。

2.8 @Builder

@Builder 是一個(gè)非常強(qiáng)大的注解,提供了一種基于建造者模式的構(gòu)建對(duì)象的 API。使用 @Builder 注解為給我們的實(shí)體類自動(dòng)生成 builder() 方法,并且直接根據(jù)字段名稱方法進(jìn)行字段賦值,最后使用 build()方法構(gòu)建出一個(gè)實(shí)體對(duì)象。

@Data
@Builder
public class User6 {
private Integer id;
private String username;
private String password;
}
@Test
public void testBuilder() {
User6 user6 = User6.builder().id(1).username("user6").password("zxc123").build();
log.warn("testLog: {}", user6); // User6(id=1, username=user6, password=zxc123)
}

需要注意的是 @Builder 不支持父類字段的生成,當(dāng)一個(gè)實(shí)體類存在父類時(shí),@Builder 只能生成當(dāng)前類的字段構(gòu)建方法。

若需要用到父類的字段方法時(shí), Lombok 提供了新的注解 @SuperBuilder 來應(yīng)對(duì)這種情況,下面是 @SuperBuilder 注解的使用方式:

@SuperBuilder
@Getter
@Setter
public class Parent {
private int id;
private String name;
}
@SuperBuilder
@Data
public class Child extends Parent {
private String childName;
}

調(diào)用示例:

Child child = Child.builder().id(1).name("父類名稱").childName("子類名稱").build();
System.out.println(child.getId());

由于 Lombok Plugin 還未更新支持@SuperBuilder,所以以上寫法在 IDEA 下還會(huì)提示編譯錯(cuò)誤,無法找到 builder()方法。

也可以參考此文方式去處理繼承的情況:reinhard.codes/2015/09/16/…

2.9 日志注解

正對(duì)程序類中常見不同框架 Logger 對(duì)象,Lombok 也提供了注解,來自動(dòng)生成 Logger 對(duì)象,實(shí)現(xiàn)優(yōu)雅地輸出日志,只需要在類上使用日志注解如 @Log。當(dāng)然 Lombok 支持了多個(gè)日志框架,并且提供對(duì)應(yīng)的注解如下:

  • @CommonsLog 等價(jià)效果: private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);
  • @Flogger 等價(jià)效果: private static final com.google.common.flogger.FluentLogger log = com.google.common.flogger.FluentLogger.forEnclosingClass();
  • @JBosLog 等價(jià)效果: private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class);
  • @Log 等價(jià)效果: private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
  • @Log4j 等價(jià)效果: private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);
  • @Log4j2 等價(jià)效果: private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);
  • @Slf4j 等價(jià)效果: private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
  • @XSlf4j 等價(jià)效果: private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);

下面代碼使用 @Slf4j 注解進(jìn)行日志輸出:

@Slf4j
public class UserTests {
// ....
@Test
public void testLog() {
User5 user5 = new User5();
user5.setId(1);
user5.setUsername("user5");
user5.setPassword("zxc123");
log.warn("testLog: {}", user5);
// 21:57:15.488 [main] WARN com.one.learn.lombok.UserTests - testLog: User5(id=1, username=user5, password=zxc123)
}
}

2.10 @Cleanup

@Cleanup 用于標(biāo)記需要釋放清理操作的資源對(duì)象變量,如 FileInputStream, FileOutputStream 等,標(biāo)記之后資源對(duì)象使用完畢后,就會(huì)被自動(dòng)關(guān)閉和清理,實(shí)際上這里 Lombok 實(shí)現(xiàn)效果與 Java7 特性 try with resource 一樣, 為我們屏蔽了關(guān)閉資源的模板代碼,下面給出 @Cleanup 的使用示例:

public class CleanupExample {
public static void main(String[] args) throws IOException {
@Cleanup InputStream in = new FileInputStream(args[0]);
@Cleanup OutputStream out = new FileOutputStream(args[1]);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) {
break;
}
out.write(b, 0, r);
}
}
}

將 CleanupExample.java 編譯生成的字節(jié)碼反編譯可以得到如下結(jié)果:

public class CleanupExample {
//...
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream(args[0]);
try {
FileOutputStream out = new FileOutputStream(args[1]);
try {
byte[] b = new byte[10000];
while(true) {
int r = in.read(b);
if (r == -1) {
return;
}
out.write(b, 0, r);
}
} finally {
if (Collections.singletonList(out).get(0) != null) {
out.close();
}
}
} finally {
if (Collections.singletonList(in).get(0) != null) {
in.close();
}
}
}
}

2.11 @SneakyThrows

@SneakyThrows 主要用于在沒有 throws 關(guān)鍵字的情況下,隱蔽地拋出受檢查異常,為我們平常開發(fā)中需要異常拋出時(shí)省去的 throw 操作,下面為使用 @SneakyThrows 的示例代碼:

public class SneakyThrowsExample implements Runnable {
@SneakyThrows(UnsupportedEncodingException.class)
public String utf8ToString(byte[] bytes) {
return new String(bytes, "UTF-8");
}
@SneakyThrows
public void run() {
throw new Throwable();
}
}

最終編譯成字節(jié)碼,反編譯結(jié)果如下:

public class SneakyThrowsExample implements Runnable {
public SneakyThrowsExample() {
}
public String utf8ToString(byte[] bytes) {
try {
return new String(bytes, "UTF-8");
} catch (UnsupportedEncodingException var3) {
throw var3;
}
}
public void run() {
try {
throw new Throwable();
} catch (Throwable var2) {
throw var2;
}
}
}

2.12 val/var

val/var 用于局部變量的修飾,有了這注解修飾后,變量的類型就會(huì)自動(dòng)通過等號(hào)右邊的表達(dá)式推斷出來,這個(gè)功能借鑒于許多編程語言的自動(dòng)類型推斷的特性。

而 val 與 var 的區(qū)別在于, val 用于修飾不可變變量,var 修飾可變變量。當(dāng) val 修飾的變量被重新賦值時(shí),編譯器就會(huì)提示異常:Error: java: 無法為最終變量 X 分配值。實(shí)際用法也比較簡單,可參考下面代碼:

@Slf4j
public class VarValExample {
public static void main(String[] args) {
val text = "abc";
// text = "1"; // Error: java: 無法為最終變量 text 分配值`。
var num = 1;
num = 2;
log.info("text:{},num:{}", text, num); // text:abc,num:2
}
}

3. 結(jié)語

到這里我們學(xué)習(xí)了 Lombok 的近乎 80% 常用的注解,應(yīng)用在我們的日常開發(fā)中已經(jīng)是綽綽有余了,開始嘗試 使用 Lombok 吧,慢慢地就會(huì)感受下效率的提升以及代碼的優(yōu)雅。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中如何比較兩個(gè)數(shù)組中元素是否相同

    Java中如何比較兩個(gè)數(shù)組中元素是否相同

    比較兩個(gè)數(shù)組中的元素是否相同,在項(xiàng)目中經(jīng)常會(huì)使用到,下面與大家分享個(gè)最簡單的方法
    2014-06-06
  • Java使用HttpClient詳細(xì)示例

    Java使用HttpClient詳細(xì)示例

    這篇文章介紹了Java使用HttpClient的詳細(xì)示例,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • Apache Commons Math3探索之多項(xiàng)式曲線擬合實(shí)現(xiàn)代碼

    Apache Commons Math3探索之多項(xiàng)式曲線擬合實(shí)現(xiàn)代碼

    這篇文章主要介紹了Apache Commons Math3探索之多項(xiàng)式曲線擬合實(shí)現(xiàn)代碼,小編覺得挺不錯(cuò)的,這里分享給大家,供需要的朋友參考。
    2017-10-10
  • Spring boot項(xiàng)目redisTemplate實(shí)現(xiàn)輕量級(jí)消息隊(duì)列的方法

    Spring boot項(xiàng)目redisTemplate實(shí)現(xiàn)輕量級(jí)消息隊(duì)列的方法

    這篇文章主要給大家介紹了關(guān)于Spring boot項(xiàng)目redisTemplate實(shí)現(xiàn)輕量級(jí)消息隊(duì)列的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • SpringMVC獲取請(qǐng)求參數(shù)筆記整理

    SpringMVC獲取請(qǐng)求參數(shù)筆記整理

    本文記錄和分享在學(xué)習(xí)Spring MVC過程中的筆記,通過案例示例代碼分析給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • 快速入門Java中的Lambda表達(dá)式

    快速入門Java中的Lambda表達(dá)式

    Lambda作為函數(shù)式編程中的基礎(chǔ)部分,在其他編程語言中早就廣為使用,但在Java領(lǐng)域中發(fā)展較慢,直到j(luò)ava8,才開始支持Lambda。網(wǎng)上關(guān)于Lambda的教程很多,今天小編給大家分享一篇快速入手Lambda的教程。
    2016-08-08
  • mybatis插件優(yōu)雅實(shí)現(xiàn)字段加密的示例代碼

    mybatis插件優(yōu)雅實(shí)現(xiàn)字段加密的示例代碼

    在很多時(shí)候,我們都需要字段加密,比如郵箱,密碼,電話號(hào)碼等,本文主要介紹了mybatis插件優(yōu)雅實(shí)現(xiàn)字段加密的示例代碼,感興趣的可以了解一下
    2023-11-11
  • springboot接收別人上傳的本地視頻實(shí)例代碼

    springboot接收別人上傳的本地視頻實(shí)例代碼

    本文通過實(shí)例代碼給大家介紹了springboot接收別人上傳的本地視頻,代碼簡單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2018-07-07
  • Spring根據(jù)XML配置文件注入屬性的方法

    Spring根據(jù)XML配置文件注入屬性的方法

    下面小編就為大家?guī)硪黄猄pring根據(jù)XML配置文件注入屬性的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-11-11
  • java實(shí)現(xiàn)word文檔轉(zhuǎn)pdf并添加水印的方法詳解

    java實(shí)現(xiàn)word文檔轉(zhuǎn)pdf并添加水印的方法詳解

    這篇文章主要介紹了java實(shí)現(xiàn)word文檔轉(zhuǎn)pdf并添加水印的方法,結(jié)合實(shí)例形式詳細(xì)分析了java word文檔轉(zhuǎn)PDF相關(guān)實(shí)現(xiàn)技巧與操作注意事項(xiàng),需要的朋友可以參考下
    2019-09-09

最新評(píng)論