java之lombok的構建者模式Builder中的泛型寫法說明
java lombok構建者模式Builder的泛型寫法
第一步:編碼
?public static <T>AjaxResult<T> success(T data) {
? ? ? ? return AjaxResult.<T>builder()
? ? ? ? ? ? ? ? .code(SUCCESS_DEFAULT_CODE)
? ? ? ? ? ? ? ? .success(true)
? ? ? ? ? ? ? ? .msg(OK)
? ? ? ? ? ? ? ? .data(data)
? ? ? ? ? ? ? ? .build();
? ? }第二步:使用:
? ? @ApiOperation(value = "查詢XXX")
? ? @PostMapping("/queryXXX")
? ? public AjaxResult<List<QueryXXXVo>> queryXXX() {
? ? ? ? return AjaxResult.success(XXXService.queryXXX());
? ? }第三步:測試
請自行測試
lombok的@Builder注解帶來的兩大坑
1、@Data和@Builder導致無參構造丟失
單獨使用@Data注解,是會生成無參數(shù)構造方法。
單獨使用@Builder注解,發(fā)現(xiàn)生成了全屬性的構造方法。
@Data和@Builder一起用:我們發(fā)現(xiàn)沒有了默認的構造方法。如果手動添加無參數(shù)構造方法或者用@NoArgsConstructor注解都會報錯!
兩種解決方法:
1、構造方法加上@Tolerate 注解,讓lombok假裝它不存在(不感知)。
@Builder
@Data
public class TestLombok {
? ? @Tolerate
? ? TestLombok() {
? ? }
? ? ......
} ? ?2、直接加上這4個注解
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TestLombok {
? ? ......
} ? ?2、@Builder注解導致默認值無效
使用Lombok注解可以極高的簡化代碼量,比較好用的注解除了@Data之外,還有@Builder這個注解,它可以讓你很方便的使用builder模式構建對象,但是今天發(fā)現(xiàn)@Builder注解會把對象的默認值清掉。
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TestLombok {
? ? private String aa = "zzzz";
? ? public static void main(String[] args) {
? ? ? ? TestLombok build = TestLombok.builder().build();
? ? ? ? System.out.println(build);
? ? }
}輸出:TestLombok(aa=null)
解決: 只需要在字段上面加上@Builder.Default注解即可
@Builder.Default private String aa = "zzzz";
3、分析原因
我們使用注解的方式,底層本質(zhì)就是反射幫我們生成了一系列的setter、getter,所以我們直接打開編譯后的target包下面的.class文件,上面的所有原因一目了然!
源文件:
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TestLombok {
? ? private String aa = "zzzz";
? ? public static void main(String[] args) {
? ? ? ? TestLombok build = TestLombok.builder().build();
? ? ? ? System.out.println(build);
? ? }
}對應的class字節(jié)碼:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.apple.ucar;
public class TestLombok {
? ? private String aa = "zzzz";
? ? public static void main(String[] args) {
? ? ? ? TestLombok build = builder().build();
? ? ? ? System.out.println(build);
? ? }
? ? public static TestLombok.TestLombokBuilder builder() {
? ? ? ? return new TestLombok.TestLombokBuilder();
? ? }
? ? public String getAa() {
? ? ? ? return this.aa;
? ? }
? ? public void setAa(String aa) {
? ? ? ? this.aa = aa;
? ? }
? ? public boolean equals(Object o) {
? ? ? ? if (o == this) {
? ? ? ? ? ? return true;
? ? ? ? } else if (!(o instanceof TestLombok)) {
? ? ? ? ? ? return false;
? ? ? ? } else {
? ? ? ? ? ? TestLombok other = (TestLombok)o;
? ? ? ? ? ? if (!other.canEqual(this)) {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? Object this$aa = this.getAa();
? ? ? ? ? ? ? ? Object other$aa = other.getAa();
? ? ? ? ? ? ? ? if (this$aa == null) {
? ? ? ? ? ? ? ? ? ? if (other$aa != null) {
? ? ? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? } else if (!this$aa.equals(other$aa)) {
? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? protected boolean canEqual(Object other) {
? ? ? ? return other instanceof TestLombok;
? ? }
? ? public int hashCode() {
? ? ? ? int PRIME = true;
? ? ? ? int result = 1;
? ? ? ? Object $aa = this.getAa();
? ? ? ? int result = result * 59 + ($aa == null ? 43 : $aa.hashCode());
? ? ? ? return result;
? ? }
? ? public String toString() {
? ? ? ? return "TestLombok(aa=" + this.getAa() + ")";
? ? }
? ? public TestLombok() {
? ? }
? ? public TestLombok(String aa) {
? ? ? ? this.aa = aa;
? ? }
? ? public static class TestLombokBuilder {
? ? ? ? private String aa;
? ? ? ? TestLombokBuilder() {
? ? ? ? }
? ? ? ? public TestLombok.TestLombokBuilder aa(String aa) {
? ? ? ? ? ? this.aa = aa;
? ? ? ? ? ? return this;
? ? ? ? }
? ? ? ? public TestLombok build() {
? ? ? ? ? ? return new TestLombok(this.aa);
? ? ? ? }
? ? ? ? public String toString() {
? ? ? ? ? ? return "TestLombok.TestLombokBuilder(aa=" + this.aa + ")";
? ? ? ? }
? ? }
}我們想知道@Data、@Builder等注解底層到底做了什么,直接編譯當前文件,即可在生成的.class字節(jié)碼文件查看具體代碼便知道了
比如上述第二點,采用@Builder的時候,這個aa并沒有默認值,所以會為空!!
? public TestLombok.TestLombokBuilder aa(String aa) {
? ? ? ? ? ? this.aa = aa;
? ? ? ? ? ? return this;
? ? ? ? }小結:個人覺得如果想要使用@Builder,最簡單的方法就是直接寫上這4個注解,有默認值的話再加上@Builder.Default直接,正常情況下就沒啥問題了!
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TestLombok {
?? ?@Builder.Default
? ? private String aa = "zzzz";
? ? public static void main(String[] args) {
? ? ? ? TestLombok build = TestLombok.builder().build();
? ? ? ? System.out.println(build);
? ? }
}總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
IntelliJ IDEA里找不到javax.servlet的jar包的解決方法
這篇文章主要介紹了IntelliJ IDEA里找不到javax.servlet的jar包的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09
mybatis-plus之自動映射字段(typeHandler)的注意點及說明
這篇文章主要介紹了mybatis-plus之自動映射字段(typeHandler)的注意點及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04
Java java.lang.InstantiationException異常案例詳解
這篇文章主要介紹了Java java.lang.InstantiationException異常案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08

