Lombok大家都知道,在使用POJO過程中,它給我們帶來了很多便利,省下大量寫get、set方法、構造器、equal、toString方法的時間。除此之外,通過@Builder注解,lombok還可以方便的實現建造者模式。
只需要定義一個靜態公共的內部類即可。代碼示例如下:
public class User { private Integer id; private String name; private String address; private User() { } private User(User origin) { this.id = origin.id; this.name = origin.name; this.address = origin.address; } public static class Builder { private User target; public Builder() { this.target = new User(); } public Builder id(Integer id) { target.id = id; return this; } public Builder name(String name) { target.name = name; return this; } public Builder address(String address) { target.address = address; return this; } public User build() { return new User(target); } }
如果項目中有使用lombok的話,可以直接使用@Builder注解來實現
改造上面的類如下:
import lombok.Builder; import lombok.ToString; /** * @author wulongtao */ @ToString @Builder public class UserExample { private Integer id; private String name; private String address; } 復制代碼 如何使用: UserExample userExample = UserExample.builder() .id(1) .name("aaa") .address("bbb") .build(); System.out.println(userExample);
遇到問題
在使用@Builder過程中,發現了一問題:子類的Builder對象沒有父類的屬性。這在使用上造成了一定的問題。
對於這個問題,找到了如下解法
- 對於父類,使用@AllArgsConstructor注解
- 對於子類,手動編寫全參數構造器,內部調用父類全參數構造器,在子類全參數構造器上使用@Builder注解
通過這種方式,子類Builder對象可以使用父類的所有私有屬性。
但是這種解法也有兩個副作用:
- 因為使用
@AllArgsConstructor
注解,父類構造函數字段的順序由聲明字段的順序決定,如果子類構造函數傳參的時候順序不一致,字段類型還一樣的話,出了錯不好發現 - 如果父類字段有增減,所有子類的構造器都要修改
雖然有這兩個副作用,但是這種解法是我找到的唯一一種解決子類使用@Builder,能使用父類屬性的方式。
參考博客評論: Lombok’s @Builder annotation and inheritance
如何在使用@Builder的模式中,加入字段的默認值。因為使用了建造者模式,那么一般在類內聲明字段的時候給字段默認值的方式就是無效的,需要在建造者上動手腳。
- 自定義靜態內部類作為建造者,賦予默認值,再使用@Builder注解,這個時候lombok會補全已有的建造者類,進而使用默認值
- 更新的lombok有@Builder.Default聲明,注解在需要默認值的字段上即可。
在評論區也有這種方式的副作用討論,鏈接是: Using Lombok’s @Builder annotation with default values
鏈接:https://juejin.im/post/6844903859387809799