天天看點

@value 預設值_如何給Lombok Builder提供預設值

@value 預設值_如何給Lombok Builder提供預設值
@value 預設值_如何給Lombok Builder提供預設值

來源:生活點亮技術

1.概覽

在這個教程中,我們将研究如何基于Lombok在實作 

Builder

模式時為屬性提供預設值。

請務必閱讀這篇Lombok簡介 。

2.Maven依賴

在本教程中,我們将使用Lombok ,是以,需要添加一個Maven依賴:

   org.projectlombok

   lombok

   1.16.18

   provided

3.基于

Lombok

Builder

的POJO

首先,讓我們看看 

Lombok

如何幫助我們從實作 

Builder

模式所需的樣闆代碼中解脫出來。 我們将從一個簡單的 

POJO

開始:

public class Pojo {

   private String name;

   private boolean original;

}

為了使這個類可用,我們需要給每個字段實作一個

getter

。另外,如果希望将這個類用于

ORM

,我們可能需要一個預設構造函數。

除了這些,我們還需要一個用于建構這個

POJO

Builder

類。有了

Lombok

,我們就可以通過一些簡單的注解來實作上面這樣功能了:

@Getter

@Builder

@NoArgsConstructor

@AllArgsConstructor

public class Pojo {

   private String name;

   private boolean original;

}

4.期望的效果

讓我們以單元測試的形式來定義想要達到的效果。

最重要,也是最基本的要求是使用

builder

方法建構對象之後要有預設值:

@Test

public void givenBuilderWithDefaultValue_ThenDefaultValueIsPresent() {

   Pojo build = Pojo.builder()

       .build();

   Assert.assertEquals("foo", build.getName());

   Assert.assertTrue(build.isOriginal());

}

當然,這個測試用例肯定會失敗,因為

@Builder

注解并不會給屬性賦預設值。 稍後,我們會讓測試通過。 如果使用了依賴預設構造函數的

ORM

架構,那麼我們應該先從預設構造函數開始:

@Test

public void givenBuilderWithDefaultValue_NoArgsWorksAlso() {

   Pojo build = Pojo.builder()

       .build();

   Pojo pojo = new Pojo();

   Assert.assertEquals(build.getName(), pojo.getName());

   Assert.assertTrue(build.isOriginal() == pojo.isOriginal());

}

在這個階段,這個測試用例通過了,因為都沒有預設值。 現在,讓我們看看如何讓這兩個測試用例都通過!

5.

Lombok

Builder.Default

注解

自從

Lombok

v1.16.16之後,我們就可以使用

@Builder.Default

注解:

// 添加在類上的注解同上

public class Pojo {

   @Builder.Default

   private String name = "foo";

   @Builder.Default

   private boolean original = true;

}

這個注解簡單易讀,但也有一些缺陷。

有了這個注解,預設值将将與構造函數一起出現,那麼第一個測試用例将通過。不幸的是,由于

@NoArgsConstructor

不會得到預設值,是以第二個測試用例失敗了。即使無參構造函數不是 

Lombok

自動生成而是顯式編寫的,也取不到預設值。

Builder.Default

注解的這種副作用從一開始就有,可能還會持續很長時間。

6.初始化

Builder

為了讓這兩個測試用例通過,我們可以嘗試通過在一個極簡的

Builder

中定義預設值:

// 添加在類上的注解同上

public class Pojo {

   private String name = "foo";

   private boolean original = true;

   public static class PojoBuilder {

       private String name = "foo";

       private boolean original = true;

   }

}

通過這種方式,這兩個測試用例都通過了。 很不幸,代價是代碼重複。對于具有數十個屬性的POJO,維護雙重初始化可能會出錯。

但是,如果願意付出這個代價,我們還應該注意一件事。如果我們使用IDE中的重構功能來重命名類,靜态内部類将不會自動重命名。這樣,

Lombok

就找不到它了,我們的代碼就出錯了。

為了消除這種風險,我們可以再配置一下

Builder

注解:

// 添加在類上的注解同上

@Builder(builderClassName = "PojoBuilder")

public class Pojo {

   private String name = "foo";

   private boolean original = true;

   public static class PojoBuilder {

       private String name = "foo";

       private boolean original = true;

   }

}

7.使用

toBuilder

參數

@Builder

還支援在原始類的執行個體中生成一個

Builder

執行個體。預設情況下這個特性是關閉的。我們可以通過在

Builder

注解中配置

toBuilder

參數來啟用:

// class annotations as before

// 添加在類上的注解同上

@Builder(toBuilder = true)

public class Pojo {

   private String name = "foo";

   private boolean original = true;

}

這樣,我們就可以避免*雙重初始化 *。

當然,這也是有代價的。我們必須通過 執行個體化這個類來建立一個

Builder

執行個體。是以,相關的測試用例也必須修改:

@Test

public void givenBuilderWithDefaultValue_ThenDefaultValueIsPresent() {

   Pojo build =  new Pojo().toBuilder()

       .build();

   Assert.assertEquals("foo", build.getName());

   Assert.assertTrue(build.isOriginal());

}

@Test

public void givenBuilderWithDefaultValue_thenNoArgsWorksAlso() {

   Pojo build = new Pojo().toBuilder()

       .build();

   Pojo pojo = new Pojo();

   Assert.assertEquals(build.getName(), pojo.getName());

   Assert.assertTrue(build.isOriginal() == pojo.isOriginal());

}

同樣,這兩個測試用例會全部通過。是以使用無參構造函數與使用

Builder

具有相同的預設值。

8.總結

至此,我們已經展示了為

Lombok

Builder

提供預設值的幾種方法。

Builder.Default

注解的副作用也很明顯。但是,其他幾個方案也有缺點。是以我們必須結合自身情況謹慎選擇。

照例,文中用到的代碼都可以在 GitHub上找到。

原文連結:https://www.baeldung.com/lombok-builder-default-value

作者: baeldung

譯者: helloworldtang

·END·

 近期熱文:

  • Spring Cloud Stream 學習小清單

  • Spring Cloud Stream 使用延遲消息實作定時任務(RabbitMQ)

  • 了解Java中的記憶體洩漏

  • Git 常用指令清單,掌握這些,輕松駕馭版本管理

  • 優先級隊列(頭條面試題)

  • 來談下高并發和分布式中的幂等處理

  • 你應該知道的7個寫出更好的 Java 代碼的技巧

  • 百億資料量下,掌握這些Redis技巧你就能Hold全場

  • 深入聊一聊 Spring AOP 實作機制

  • 我說分布式事務之最大努力通知型事務

  • 我說分布式事務之TCC

  • 不可錯過的CMS學習筆記

  • 可能是最全面的G1學習筆記

@value 預設值_如何給Lombok Builder提供預設值

看完,趕緊點個“好看”鴨

點鴨點鴨

↓↓↓↓

繼續閱讀