帶有繼承的Lombok Builder

2021-10-10 19:30:53 字數 4718 閱讀 4183

3。 @ superbuilder*和繼承

4。結論

lombok庫提供了一種無需編寫任何樣板**即可實現* builder pattern的好方法: [@builder](https:// projectlombok.org/features/builder)*注釋。

在這個簡短的教程中,我們將專門學習涉及繼承時如何處理@ builder注釋。我們將演示兩種技術。一種依賴於標準的lombok功能。另乙個則利用了lombok 1.18中引入的實驗功能。

有關builder注釋的更廣泛概述,請參考使用lombok的@ builder注釋。

project lombok簡介中也提供了有關project lombok庫的詳細資訊。

假設我們的child類擴充套件了parent類:

@getter

@allargsconstructor

public

class

parent

@getter

@builder

public

class

child

extends

parent

在擴充套件了此類的另乙個類上使用@ builder時,我們將在注釋上收到以下編譯錯誤:

隱式超級建構函式parent()未定義。必須顯式呼叫另乙個建構函式

這是由於lombok不考慮超類的字段,而僅考慮了當前類的字段。

對我們來說幸運的是,有乙個簡單的解決方法。我們可以(使用我們的ide甚至手動生成)基於欄位的建構函式。這也包括超類的字段。我們用@ builder而不是類來注釋它:

@getter

@allargsconstructor

public

class

parent

@getter

public

class

child

extends

parent

}

這樣,我們將能夠從child類訪問便捷的構建器,這將使我們也可以指定parent類的字段:

child child = child.

builder()

.parentname

("andrea").

parentage(38

).childname

("emma").

childage(6

).build()

;assertthat

(child.

getparentname()

).isequalto

("andrea");

assertthat

(child.

getparentage()

).isequalto(38

);assertthat

(child.

getchildname()

).isequalto

("emma");

assertthat

(child.

getchildage()

).isequalto(6

);

如果超類本身使用@ builder進行注釋,則在注釋child類的建構函式時會出現以下錯誤:

返回型別與parent.builder()不相容

這是因為child類正試圖公開兩個具有相同名稱的builders。

我們可以通過為至少乙個構建器方法分配唯一的名稱來解決此問題:

@getter

public

class

child

extends

parent

}

然後,我們將能夠通過child.builder()獲得 parentbuilder,並通過child.childbuilder()獲得 childbuilder。

在某些情況下,我們可能需要支援更深的繼承層次結構。我們可以使用與以前相同的模式。讓我們建立child的子類。

@getter

public

class

student

extends

child

}

和以前一樣,我們需要手動新增乙個建構函式。這需要接受所有父類和子類的所有屬性作為引數。然後,像以前一樣新增@ builder批註。通過在注釋中提供另乙個唯一的方法名稱,我們可以獲得parent,child或student的構建器。

student student = student.

studentbuilder()

.parentname

("andrea").

parentage(38

).childname

("emma").

childage(6

).schoolname

("baeldung high school").

build()

;assertthat

(student.

getchildname()

).isequalto

("emma");

assertthat

(student.

getchildage()

).isequalto(6

);assertthat

(student.

getparentname()

).isequalto

("andrea");

assertthat

(student.

getparentage()

).isequalto(38

);assertthat

(student.

getschoolname()

).isequalto

("baeldung high school"

);

然後,我們可以擴充套件此模式以處理任何繼承深度。我們需要建立的建構函式可能會變得很大,但是您的ide可以幫助您。

如我們前面所述,lombok的1.18版引入了* @ superbuilder*批註。我們可以使用它來以更簡單的方式解決問題。

我們可以使建造者能夠看到其祖先的屬性。

為此,我們使用@ superbuilder批註對我們的類及其祖先進行批註。

讓我們在這裡演示我們的三層層次結構。請注意,簡單父級和子級繼承的原理是相同的:

@getter

@superbuilder

public

class

parent

{// same as before...

@getter

@superbuilder

public

class

child

extends

parent

{// same as before...

@getter

@superbuilder

public

class

student

extends

child

{// same as before...

當所有類都以這種方式注釋後,我們將為子類獲得乙個構建器,該構建器也公開了父級的屬性。

注意,我們必須注釋所有類。 @ superbuilder不能在同一類層次結構中與@ builder混合。這樣做會導致編譯錯誤。

這一次,我們不需要定義任何特殊的建構函式。由@ superbuilder生成的生成器類的行為就像我們使用主lombok @ builder生成的生成器類一樣:

student student = student.

builder()

.parentname

("andrea").

parentage(38

).childname

("emma").

childage(6

).schoolname

("baeldung high school").

build()

;assertthat

(student.

getchildname()

).isequalto

("emma");

assertthat

(student.

getchildage()

).isequalto(6

);assertthat

(student.

getparentname()

).isequalto

("andrea");

assertthat

(student.

getparentage()

).isequalto(38

);assertthat

(student.

getschoolname()

).isequalto

("baeldung high school"

);

我們已經看到了如何處理在利用繼承的類中使用@ builder注釋的常見陷阱。

如果使用主要的lombok @ builder批註,我們還有一些額外的步驟可以使它起作用。但是,如果我們願意使用實驗性功能,那麼@ superbuilder可以簡化事情。

和往常一樣,完整的源**可在[github上]獲得(

帶有泛型的類如何繼承

public class genericitytst 具有泛型的classa public class classa 繼承泛型 public class classb extends classa 縮小泛型的範圍,是准許的,但是不允許擴大泛型的範圍 public class classc exten...

帶有虛函式的菱形繼承和帶有虛函式的菱形虛繼承

對於某些函式來說,基類希望它的派生類定義適合自身的版本,此時基類就將這些函式宣告為虛函式。在存在虛函的類,建立物件時會產生虛表指標,虛表指標指向乙個虛表,這時就可以通過虛表訪問自己定義的函式。通過下面兩種繼承進行分析 帶有虛函式的菱形繼承 以下圖的模型為例進行分析 我們觀察c類物件在記憶體中的結構 ...

帶有風的詩詞 帶有風字的詩句

帶有風字的詩句 1 昨夜秋風入漢關,朔雲邊月滿西山。嚴武 軍城早秋 2 夜來風雨聲,花落知多少。孟浩然 春曉 3 相見時難別亦難,東風無力百花殘。李商隱 無題 4 古道西風瘦馬,夕陽西下,斷腸人在天涯。馬致遠 天淨沙 秋思 5 大風起兮雲飛揚。劉邦 大風歌 6 忽如一夜春風來,千樹萬樹梨花開。岑參 ...