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

java如何使用Lombok更優(yōu)雅地編碼

 更新時間:2019年06月10日 10:32:20   作者:鍋外的大佬  
Lombok能通過注解的方式,在編譯時自動為屬性生成構(gòu)造器、getter/setter、equals、hashcode、toString方法。這樣就省去了手動重建這些代碼的麻煩,使代碼看起來更簡潔些。下面我們來詳細(xì)學(xué)習(xí)下吧

Lombok簡介

和其他語言相比,Java經(jīng)常因為不必要的冗長被批評。Lombok提供了一系列注解用以在后臺生成模板代碼,將其從你的類中刪除,從而有助于保持你的代碼整潔。較少的模板意味著更簡潔的代碼,更易于閱讀和維護。在本文中,我將涉及我經(jīng)常使用的Lombok功能,并想你展示如何使用他們生產(chǎn)更清晰、更簡潔的代碼。

1.局部變量類型推斷:val 和 var

許多語言通過查看等號右側(cè)的表達(dá)式來推斷局部變量類型。盡管現(xiàn)在Java 10+已經(jīng)支持這種功能,但在之前的版本中沒有Lombok的幫助就無法實現(xiàn)。下面的代碼段展示了如何顯式指定局部類型:

final Map<String, Integer> map = new HashMap<>();
map.put("Joe", 21);

在Lombok中,我們可以通過使用val來縮短它,如下所示:

val valMap = new HashMap<String, Integer>();
valMap.put("Sam", 30);

注意,val在背后創(chuàng)建了一個final且不可變的變量。如果你需要一個可變本地變量,可以使用var。

2.@NonNull

對方法參數(shù)進(jìn)行null檢查通常不是一個壞主意,特別是如果該方法形成的API被其他開發(fā)者使用。雖然這些檢查很簡單,但是他們可能變得冗長,特別是當(dāng)你有多個參數(shù)時。如下所示,額外的代碼無助于可讀性,并且可能從方法的主要目的分散注意力。

public void nonNullDemo(Employee employee, Account account) {
if(employee == null) {
throw new IllegalArgumentException("Employee is marked @NonNull but is null");
}
if(account == null) {
throw new IllegalArgumentException("Account is marked @NonNull but is null");
}
// do stuff
}

理想情況下,你需要null檢查——沒有干擾的那種。這就是@NonNull發(fā)揮作用的地方。通過用@NonNull標(biāo)記參數(shù),Lombok替你為該參數(shù)生成null檢查。你的方法突然變得更加簡潔,但沒有丟失那些安全性的null檢查。

public void nonNullDemo(@NonNull Employee employee, @NonNull Account account) {
// just do stuff
}

默認(rèn)情況下,Lombok會拋出NullPointerException,如果你愿意,可以配置 Lombok拋出IllegalArgumentException。我個人更喜歡IllegalArgumentException,因為我認(rèn)為它更適合于對參數(shù)檢查。

##3.更簡潔的數(shù)據(jù)類 數(shù)據(jù)類是Lombok真正有助于減少模板代碼的領(lǐng)域。在查看該選項前,思考一下我們經(jīng)常需要處理的模板種類。數(shù)據(jù)類通常包括以下一種或全部:

  • 構(gòu)造函數(shù)(有或沒有參數(shù))
  • 私有成員變量的 getter 方法
  • 私有非 final 成員變量的 setter 方法
  • 幫助記錄日志的 toString 方法
  • equals 和 hashCode(處理相等/集合)

可以通過 IDE 生成以上內(nèi)容,因此問題不在于編寫他們花費的時間。問題是帶有少量成員變量的簡單類很快會變得非常冗長。讓我們看看Lombok如何通過處理上述的每一項來減少混亂。

3.1. @Getter 和 @Setter

想想下面的Car類。當(dāng)生成getter和setter時,我們會得到接近 50 行代碼來描述一個包含 5 個成員變量的類。

public class Car {
private String make;
private String model;
private String bodyType;
private int yearOfManufacture;
private int cubicCapacity;
public String getMake() {
return make;
}
public void setMake(String make) {
this.make = make;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getBodyType() {
return bodyType;
}
public void setBodyType(String bodyType) {
this.bodyType = bodyType;
}
public int getYearOfManufacture() {
return yearOfManufacture;
}
public void setYearOfManufacture(int yearOfManufacture) {
this.yearOfManufacture = yearOfManufacture;
}
public int getCubicCapacity() {
return cubicCapacity;
}
public void setCubicCapacity(int cubicCapacity) {
this.cubicCapacity = cubicCapacity;
}
}

Lombok可以替你生成getter和setter模板。通過對每個成員變量使用 @Getter和@Setter注解,你最終得到一個等效的類,如下所示:

public class Car {
@Getter @Setter
private String make;
@Getter @Setter
private String model;
@Getter @Setter
private String bodyType;
@Getter @Setter
private int yearOfManufacture;
@Getter @Setter
private int cubicCapacity;
}

注意,你可以在非final成員變量上只使用@Setter。在final成員變量上使用它將導(dǎo)致編譯錯誤。

如果你需要為每個成員變量生成getter和setter,你也可以在類級別使用 @Getter和@Setter,如下所示。

@Getter 
@Setter
public class Car {
private String make;
private String model;
private String bodyType;
private int yearOfManufacture;
private int cubicCapacity;
}

3.2. @AllArgsConstructor

數(shù)據(jù)類通常包含一個構(gòu)造函數(shù),它為每個成員變量接受參數(shù)。IDE 為Car生成的構(gòu)造函數(shù)如下所示:

public class Car {
@Getter @Setter
private String make;
@Getter @Setter
private String model;
@Getter @Setter
private String bodyType;
@Getter @Setter
private int yearOfManufacture;
@Getter @Setter
private int cubicCapacity;
public Car(String make, String model, String bodyType, int yearOfManufacture, int cubicCapacity) {
super();
this.make = make;
this.model = model;
this.bodyType = bodyType;
this.yearOfManufacture = yearOfManufacture;
this.cubicCapacity = cubicCapacity;
}
}

我們可以使用@AllArgsConstructor注解實現(xiàn)同樣功能。@Getter和 @Setter、@AllArgsConstructor減少模板,保持類更干凈且更簡潔。

@AllArgsConstructor
public class Car {
@Getter @Setter
private String make;
@Getter @Setter
private String model;
@Getter @Setter
private String bodyType;
@Getter @Setter
private int yearOfManufacture;
@Getter @Setter
private int cubicCapacity;
}

還有其他選項用于生成構(gòu)造函數(shù)。@RequiredArgsConstructor將創(chuàng)建帶有每個 final成員變量參數(shù)的構(gòu)造函數(shù),@NoArgsConstructor將創(chuàng)建沒有參數(shù)的構(gòu)造函數(shù)。

3.3. @ToString

在你的數(shù)據(jù)類上覆蓋toString方法是有助于記錄日志的良好實踐。IDE 為Car類生成的toString方法如下所示:

@AllArgsConstructor
public class Car {
@Getter @Setter
private String make;
@Getter @Setter
private String model;
@Getter @Setter
private String bodyType;
@Getter @Setter
private int yearOfManufacture;
@Getter @Setter
private int cubicCapacity;
@Override
public String toString() {
return "Car [make=" + make + ", model=" + model + ", bodyType=" + bodyType + ", yearOfManufacture="
+ yearOfManufacture + ", cubicCapacity=" + cubicCapacity + "]";
}
}

我們可以使用ToString注解廢除這個,如下所示:

@ToString
@AllArgsConstructor
public class Car {
@Getter @Setter
private String make;
@Getter @Setter
private String model;
@Getter @Setter
private String bodyType;
@Getter @Setter
private int yearOfManufacture;
@Getter @Setter
private int cubicCapacity;
}

默認(rèn)情況下,Lombok生成包含所有成員變量的toString方法。可以通過 exclude屬性@ToString(exclude={"someField"}, "someOtherField"}) 覆蓋行為將某些成員變量排除。

3.4. @EqualsAndHashCode

如果你正在將你的數(shù)據(jù)類和任何類型的對象比較,則需要覆蓋equals和hashCode 方法。對象的相等是基于業(yè)務(wù)規(guī)則定義的。舉個例子,在Car類中,如果兩個對象有相同的make、model和bodyType,我可能認(rèn)為他們是相等的。如果我使用 IDE 生成equals方法檢查make、model和bodyType,它看起來會是這樣:

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Car other = (Car) obj;
if (bodyType == null) {
if (other.bodyType != null)
return false;
} else if (!bodyType.equals(other.bodyType))
return false;
if (make == null) {
if (other.make != null)
return false;
} else if (!make.equals(other.make))
return false;
if (model == null) {
if (other.model != null)
return false;
} else if (!model.equals(other.model))
return false;
return true;
}

等價的hashCode實現(xiàn)如下所示:

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((bodyType == null) ? 0 : bodyType.hashCode());
result = prime * result + ((make == null) ? 0 : make.hashCode());
result = prime * result + ((model == null) ? 0 : model.hashCode());
return result;
}

雖然 IDE 處理了繁重的工作,但我們在類中仍然有大量的模板代碼。Lombok允許我們使用@EqualsAndHashCode類注解實現(xiàn)相同的功能,如下所示:

@ToString
@AllArgsConstructor
@EqualsAndHashCode(exclude = { "yearOfManufacture", "cubicCapacity" })
public class Car {
@Getter @Setter
private String make;
@Getter @Setter
private String model;
@Getter @Setter
private String bodyType;
@Getter @Setter
private int yearOfManufacture;
@Getter @Setter
private int cubicCapacity;
}

默認(rèn)情況下,@EqualsAndHashCode會創(chuàng)建包含所有成員變量的equals和 hashCode方法。exclude選項可用于通知Lombok排除某些成員變量。

在上面的代碼片段中。我已經(jīng)從生成的equals和hashCode方法中排除了 yearOfManuFacture 和cubicCapacity。

3.5. @Data

如果你想使數(shù)據(jù)類盡可能精簡,可以使用@Data注解。@Data 是@Getter、@Setter、@ToString、@EqualsAndHashCode 和 @RequiredArgsConstructor 的快捷方式。

@ToString
@RequiredArgsConstructor
@EqualsAndHashCode(exclude = { "yearOfManufacture", "cubicCapacity" })
public class Car {
@Getter @Setter
private String make;
@Getter @Setter
private String model;
@Getter @Setter
private String bodyType;
@Getter @Setter
private int yearOfManufacture;
@Getter @Setter
private int cubicCapacity; 
}

通過使用@Data,我們可以將上面的類精簡如下:

@Data
public class Car {
private String make;
private String model;
private String bodyType;
private int yearOfManufacture;
private int cubicCapacity; 
}

4. 使用 @Buidler 創(chuàng)建對象

建造者設(shè)計模式描述了一種靈活的創(chuàng)建對象的方式。Lombok可以幫你輕松的實現(xiàn)該模式??匆粋€使用簡單Car類的示例。假設(shè)我們希望可以創(chuàng)建各種Car對象,但我們希望在創(chuàng)建時設(shè)置的屬性具有靈活性。

@AllArgsConstructor
public class Car {
private String make;
private String model;
private String bodyType;
private int yearOfManufacture;
private int cubicCapacity; 
private List<LocalDate> serviceDate;
}

假設(shè)我們要創(chuàng)建一個Car,但只想設(shè)置make和model。在Car上使用標(biāo)準(zhǔn)的全參數(shù)構(gòu)造函數(shù)意味著我們只提供make和model并設(shè)置其他參數(shù)為null。

Car2 car2 = new Car2("Ford", "Mustang", null, null, null, null);

這可行但并不理想,我們必須為我們不感興趣的參數(shù)傳遞null。我們可以創(chuàng)建一個只接受make和model的構(gòu)造函數(shù)來避開這個問題。這是一個合理的解決方法,但不夠靈活。如果我們有許多不同的字段排列,我們可以用什么來創(chuàng)建一個新Car?最終我們得到了一堆不同的構(gòu)造函數(shù),代表了我們可以實例化Car的所有可能方式。

解決該問題的一種干凈、靈活的方式是使用建造者模式。Lombok通過@Builder 注解幫你實現(xiàn)建造者模式。當(dāng)你使用@Builder注解Car類時,Lombok會執(zhí)行以下操作:

  • 添加一個私有構(gòu)造函數(shù)到Car
  • 創(chuàng)建一個靜態(tài)的CarBuilder類
  • 在CarBuilder中為Car中的每個成員創(chuàng)建一個setter風(fēng)格方法。
  • 在CarBuilder中添加創(chuàng)建Car的新實例的建造方法。

CarBuilder上的每個setter風(fēng)格方法返回自身的實例(CarBuilder)。這允許你進(jìn)行方法鏈?zhǔn)秸{(diào)用并為對象創(chuàng)建提供流暢的 API。讓我們看看它如何使用。

Car muscleCar = Car.builder().make("Ford")
.model("mustang")
.bodyType("coupe")
.build();

現(xiàn)在只使用make和model創(chuàng)建Car比之前更簡潔了。只需在Car上簡單的調(diào)用生成的builder方法獲取CarBuilder實例,然后調(diào)用任何我們感興趣的setter風(fēng)格方法。最后,調(diào)用build創(chuàng)建Car的新實例。

另一個值得一提的方便的注解是@Singular。默認(rèn)情況下,Lombok 為集合創(chuàng)建使用集合參數(shù)的標(biāo)準(zhǔn)的 setter 風(fēng)格方法。在下面的例子中,我們創(chuàng)建了新的 Car并設(shè)置了服務(wù)日期列表。

Car muscleCar = Car.builder().make("Ford")
.model("mustang")
.serviceDate(Arrays.asList(LocalDate.of(2016, 5, 4)))
.build();

向集合成員變量添加@Singular將提供一個額外的方法,允許你向集合添加單個項。

@Builder
public class Car {
private String make;
private String model;
private String bodyType;
private int yearOfManufacture;
private int cubicCapacity; 
@Singular
private List<LocalDate> serviceDate;
}

現(xiàn)在我們可以添加單個服務(wù)日期,如下所示:

Car muscleCar3 = Car.builder()
.make("Ford")
.model("mustang")
.serviceDate(LocalDate.of(2016, 5, 4))
.build();

這是一個有助于在創(chuàng)建對象期間處理集合時保持代碼簡潔的快捷方法。

5.日志

Lombok另一個偉大的功能是日志記錄器。如果沒有Lombok,要實例化標(biāo)準(zhǔn)的 SLF4J日志記錄器,通常會有以下內(nèi)容:

public class SomeService {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
public void doStuff(){
log.debug("doing stuff....");
}
}

這些日志記錄器很沉重,并為每個需要日志記錄的類添加了不必要的混亂。值得慶幸的是 Lombok提供了一個為你創(chuàng)建日志記錄器的注解。你要做的所有事情就是在類上添加注解,這樣就可以了。

@Slf4j
public class SomeService {
public void doStuff(){
log.debug("doing stuff....");
}
}

我在這里使用了@SLF4J注解,但Lombok能為幾乎所有通用Java日志框架生成日志記錄器。有關(guān)更多日志記錄器的選項,請參閱文檔。

6.Lombok給你控制權(quán)

我非常喜歡Lombok的一點是它的不侵入性。。如果你決定在使用如@Getter、@Setter 或 @ToString時也想要自己的方法實現(xiàn),你的方法將總是優(yōu)先于 Lombok。它允許你在大多數(shù)時間使用Lombok,但在你需要的時候仍有控制權(quán)。

7.寫得更少,做得更多

在過去的 4 到 5 年里,我?guī)缀踉诿總€項目中都使用了Lombok。我喜歡它,因為它減少了雜亂,最終得到了更干凈、更簡潔、更易閱讀的代碼。它不一定為你節(jié)省大量時間,因為它生成的代碼可以由 IDE 自動生成。話雖如此,我認(rèn)為更干凈的代碼的好處不僅僅是將其添加到Java堆棧中。

8. 延展閱讀

我已經(jīng)介紹了我經(jīng)常使用的Lombok功能,但還有很多我沒有講到。如果你喜歡目前為止所看到的,并希望了解更多,請繼續(xù)閱讀 Lombok 文檔。

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

相關(guān)文章

  • java中調(diào)用super的實例講解

    java中調(diào)用super的實例講解

    在本篇文章里小編給大家分享了一篇關(guān)于java中調(diào)用super的實例講解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2020-12-12
  • Spring Cloud基于zuul實現(xiàn)網(wǎng)關(guān)過程解析

    Spring Cloud基于zuul實現(xiàn)網(wǎng)關(guān)過程解析

    這篇文章主要介紹了Spring Cloud基于zuul實現(xiàn)網(wǎng)關(guān)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12
  • MyBatis自定義映射關(guān)系和關(guān)聯(lián)查詢實現(xiàn)方法詳解

    MyBatis自定義映射關(guān)系和關(guān)聯(lián)查詢實現(xiàn)方法詳解

    這篇文章主要介紹了MyBatis自定義映射關(guān)系和關(guān)聯(lián)查詢實現(xiàn)方法,當(dāng)POJO屬性名與數(shù)據(jù)庫列名不一致時,需要自定義實體類和結(jié)果集的映射關(guān)系,在MyBatis注解開發(fā)中,使用@Results定義并使用自定義映射,使用 @ResultMap使用自定義映射
    2023-04-04
  • 解讀Spring接口方法加@Transactional失效的原因

    解讀Spring接口方法加@Transactional失效的原因

    這篇文章主要介紹了Spring接口方法加@Transactional失效的原因解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 聊聊SpringBoot中組件無法被注入的問題

    聊聊SpringBoot中組件無法被注入的問題

    這篇文章主要介紹了SpringBoot中組件無法被注入的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java流程控制之循環(huán)結(jié)構(gòu)for,增強for循環(huán)

    Java流程控制之循環(huán)結(jié)構(gòu)for,增強for循環(huán)

    這篇文章主要介紹了Java流程控制之循環(huán)結(jié)構(gòu)for,增強for循環(huán),for循環(huán)是編程語言中一種循環(huán)語句,而循環(huán)語句由循環(huán)體及循環(huán)的判定條件兩部分組成,其表達(dá)式為:for(單次表達(dá)式;條件表達(dá)式;末尾循環(huán)體){中間循環(huán)體;},下面我們倆看看文章內(nèi)容的詳細(xì)介紹
    2021-12-12
  • java實現(xiàn)小i機器人api接口調(diào)用示例

    java實現(xiàn)小i機器人api接口調(diào)用示例

    這篇文章主要介紹了java實現(xiàn)小i機器人api接口調(diào)用示例,需要的朋友可以參考下
    2014-04-04
  • SpringBoot之Controller的使用詳解

    SpringBoot之Controller的使用詳解

    本篇文章主要介紹了SpringBoot之Controller的使用詳解,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-08-08
  • MyBatis-Plus QueryWrapper及LambdaQueryWrapper的使用詳解

    MyBatis-Plus QueryWrapper及LambdaQueryWrapper的使用詳解

    這篇文章主要介紹了MyBatis-Plus QueryWrapper及LambdaQueryWrapper的使用詳解,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • org.springframework.beans.BeanInstantiationException異常解決

    org.springframework.beans.BeanInstantiationException異常解決

    本文主要介紹了org.springframework.beans.BeanInstantiationException異常解決,大多數(shù)情況下,這個異常是由于簡單的配置錯誤或者代碼問題導(dǎo)致的,下面就來具體解決一下
    2024-03-03

最新評論