Lombok是什么糊饱?
一個在編譯階段修改增強Java類的工具,使用方式基于注解颠黎,常用于:
- 為Java POJO生成屬性對應(yīng)的getter,setter等
- 為Java POJO生成builder構(gòu)造器模式的實現(xiàn)
- 為Java類自動添加其他重復(fù)性代碼另锋,比如日志記錄的聲明代碼可以通過@Slf4j注解添加
項目中是否引入Lombok一直是個存在爭議,它的主要優(yōu)勢在于消除Java類的部分臃腫代碼狭归,提高開發(fā)效率夭坪,降低代碼維護成本;缺點是需要IDE插件支持过椎,需要團隊統(tǒng)一規(guī)范室梅,另外某些注解生成的隱性實現(xiàn)可能導(dǎo)致問題跟蹤調(diào)試困難。
不使用Lombok疚宇,IDE也可以自動生成getter,setter代碼亡鼠,但Lombok除了getter,setter還有@Builder和@SuperBuilder等非常實用的自動實現(xiàn)。比如你可以將一個POJO類轉(zhuǎn)化為builder模式敷待,如果你又有一個子類间涵,子類的構(gòu)造器還要繼承自父類,寫起來就費勁了讼撒。而通過Lombok只需要一個@SuperBuilder注解(v1.18.2+版本支持)浑厚。
如何引入Lombok
- 引入依賴,以gradle為例:
compile("org.projectlombok:lombok:1.18.4")
- IDE中安裝插件根盒,以IDEA為例: Settings -> Plugins -> 搜索Lombok Plugin钳幅,點擊安裝
- IDEA中配置啟用注解的處理: Enable annotation processing (不開啟將導(dǎo)致編譯錯誤)
Lombok常見用法
- 在屬性上添加的注解: @Getter、@Setter炎滞、@NonNull等:
示例代碼:
public class Parent {
// get,set添加在指定屬性上
@Getter @Setter private int id;
@Getter @Setter private String name;
}
-
在類上添加的注解:
- @Data 注解組合敢艰,含@Setter、@Getter册赛、@RequiredArgsConstructor钠导、@EqualsAndHashCode等注解 - 構(gòu)造函數(shù)注解: @NoArgsConstructor震嫉、@AllArgsConstructor、@RequiredArgsConstructor - 構(gòu)造器builder注解: @Builder牡属、@SuperBuilder - 日志聲明的注解: @Slf4j 等
示例代碼:
@Data
public class Child extends Parent {
private String ext;
}
@Setter@Getter或@Data注解添加后可以通過new創(chuàng)建對象并調(diào)用getter票堵,setter方法:
Child c1 = new Child();
c1.setId(1);
System.out.println(c1.getId());
Builder構(gòu)造器模式與繼承
構(gòu)造模式的鏈式調(diào)用寫起來很方便,自己實現(xiàn)構(gòu)造模式要在POJO類中寫較多代碼逮栅,尤其是需要繼承父類的builder時悴势。
Lombok的@Builder注解可以方便的支持構(gòu)造模式
示例代碼:
@Builder
public class Child extends Parent {
private String ext;
}
調(diào)用方法:
Child c1 = Child.builder().ext("子類屬性ext").build();
System.out.println(c1.getExt());
此例中的鏈式調(diào)用僅有ext()屬性,即使給父類Parent也添加@Builder注解也依然不能鏈式調(diào)用id()和name()措伐,自己去寫builder的實現(xiàn)也是這樣特纤,類是繼承的,但類中的builder并無繼承關(guān)系侥加,而實際開發(fā)場景中我們一般都需要讓子類的builder繼承父類builder的行為捧存。
Lombok在v1.18.2版本中針對這個問題增加了@SuperBuilder注解,子類和父類中都添加@SuperBuilder注解担败,子類builder即可繼承父類builder昔穴。
代碼示例:
@SuperBuilder
public class Parent {
// get,set添加在指定屬性上
@Getter @Setter private int id;
//如果需要讓build出的對象屬性使用默認值,需要添加@Builder.Default注解
@Builder.Default
@Getter @Setter private String name = "unknown";
}
@SuperBuilder
@Data
public class Child extends Parent {
private String ext;
}
調(diào)用示例:
Child c1 = Child.builder().id(1).name("名稱").ext("子類屬性ext").build();
System.out.println(c1.getId());
需要注意的是: 關(guān)于builder的繼承提前,Lombok Plugin尚未更新支持@SuperBuilder傻咖,所以以上寫法在IDE下還會提示編譯錯誤,等更新吧岖研,或者用稍微蹩腳一點的解決方案:Lombok’s @Builder annotation and inheritance