天天看點

lombok使用基礎教程

lombok是一個編譯級别的插件,它可以在項目編譯的時候生成一些代碼。在很多工具類的項目中都有這個功能。比如dagger。

通俗的說,lombok可以通過注解來标示生成<code>getter</code> <code>settter</code>等代碼。我們自然可以通過編譯器比如IDEA的<code>Generate</code>生成,為啥要用這個?

在項目開發階段,一個class的屬性是一直變化的,今天可能增加一個字段,明天可能删除一個字段。每次變化都需要修改對應的模闆代碼。另外,有的class的字段超級多,多到一眼看不完。如果加上模闆代碼,更難一眼看出來。更有甚者,由于字段太多,想要使用builder來建立。手動建立builder和字段和原來的類夾雜在一起,看起來真的難受。lombok的<code>@Builder</code>即可解決這個問題。

引入就是加入<code>lombok</code>的jar包。

直接加入依賴

這裡比較麻煩,需要添加一個編譯時生成代碼的插件。gradle裡有幾個這樣的插件。但為了簡化過程,lombok提供了新插件。

首先,添加一個plugin

然後,就可以了。還可以配置lombok的版本:

在IDEA裡使用需要添加一個插件。在插件裡搜尋lombok,安裝,重新開機。

lombok使用基礎教程

IDEA裡需要在設定中啟用annotation processors。

lombok使用基礎教程

最簡單的,最常用的,最直覺的使用就是getter setter方法。

簡單使用沒有問題,深入一點可以看到有些特殊設定。比如javadoc.

<code>Getter</code>聲明建立getter方法;

<code>Setter</code>聲明建立setter方法;

<code>@Setter(AccessLevel.PROTECTED)</code>可以添加參數,指定權限為私有;

Attention!關于<code>boolean</code>的set字首都是set,但getter不同,小寫的<code>boolean</code>,即基本類型,字首是<code>is</code>; <code>Boolean</code>,即包裝類型,字首是<code>get</code>;

編譯後的結果如下:

1.<code>@ToString</code>最簡單使用即可

列印結果如下:

ToStringExample(name=abc, shape=ToStringExample.Square(super=ToStringExample.Shape(color=0), width=1, height=2), tags=[a, b, c])

編譯後的代碼如下:

equals()和hashCode()在Java中有着舉足輕重的基地作用,雖然通常很少關注。但是,這個必須不可省。不知道有幾個可以手寫出來的。

編譯後的結果為:

Java中class的一切起源于構造器。大家最喜歡的還是構造函數建立對象。這裡有一點比較坑的是無參構造函數。當你自己添加一個帶有參數的構造函數後,無參構造函數則别隐藏。通常也沒啥問題,但當你使用jackson反序列化對象的時候就被惡心到了。jackson通過無參構造函數建立對象。是以,當你考慮這個class會用來序列化為json的時候,即必須手動添加一個無參數構造函數。

當你想要建立一個valueobject,DDD中的值對象,要求實作Immutable,那麼無參數構造器就不合适了。<code>@NoArgsConstructor</code>會生成一個空的構造器。如果你設定了final field,那麼編譯會報錯。如果你強制執行建立無參數構造器。即,<code>@NoArgsConstructor(force = true)</code>,那麼final的field會初始化為<code>0</code>/<code>false</code>/<code>null</code>。通常适合與<code>@Data</code>內建。

<code>NonNull</code>被忽略了

最終生成代碼如下:

對于final的字段,我認為我不會用空構造器來做這件事。是以,感覺這個參數<code>force=true</code>不要也罷,雞肋。

一個class可以有很多屬性,但你可能隻關心其中的幾個字段,那麼可以使用<code>@RequiredArgsConstructor</code>。<code>@NonNull</code>将标注這個字段不應為null,初始化的時候會檢查是否為空,否則抛出<code>NullPointException</code>。在上面的無參構造函數中被忽略了。那麼,對于關注的字段标注<code>@NonNull</code>, <code>@RequiredArgsConstructor</code>則會生成帶有這些字段的構造器。

最終生成結果:

隻有<code>@NonNull</code>會生成構造器。其他預設,Java的class初始化預設為null.false,0.

lombok提供了另一種初始化做法,靜态初始化。即私有構造器,使用靜态方法建立對象。這種做法看起來簡單,但通常用的不多。因為靜态初始化的東西很難mock,對測試不夠友好。

想要初始化所有字段。

<code>@Data</code>是一個集合體。包含<code>Getter</code>,<code>Setter</code>,<code>RequiredArgsConstructor</code>,<code>ToString</code>,<code>EqualsAndHashCode</code>

這個看起來很美好,就是可以幫忙生成一個不可變對象。對于所有的字段都将生成final的。但我感覺有點失控。注解的優勢應該是所見即所得,可以通過字面量來傳遞消息。而<code>@Value</code>字段給字段加final會讓人困惑,因為這更改了我們的定義。當我想聲明一個Immutable對象的時候,我會顯示的給字段加一個限定final。

同<code>@Data</code>, <code>@Value</code>是一個集合體。包含<code>Getter</code>,<code>AllArgsConstructor</code>,<code>ToString</code>,<code>EqualsAndHashCode</code>。

編譯後

對于喜歡builder模式的人來說,聲明式簡化對象建立流程讓一切看得美好。但是,手動複制字段,手動建立方法很讓人不喜。<code>@Builder</code>解決了剛需。

這才是我們想要的建造者。對應生成的代碼為:

lombok還提供了其他幾個注解,以及還有好多内置的參數沒有講解。但是,根據2-8原理,我們根本不需要。上面這幾個足夠了。更多的注解隻會增加了解閱讀難度。

<a href="https://projectlombok.org/features/all">https://projectlombok.org/features/all</a>

<a href="http://kriszhang.com/lombok/">http://kriszhang.com/lombok/</a>

唯有不斷學習方能改變!

-- <b>Ryan Miao</b>