@Builder @Data public class TestLombok { @Tolerate TestLombok() { } ...... }
@Data @Builder @NoArgsConstructor @AllArgsConstructor public class TestLombok { ...... }
使用Lombok註解能夠極高的簡化代碼量,比較好用的註解除了@Data以外,還有@Builder這個註解,它可讓你很方便的使用builder模式構建對象,可是今天發現@Builder註解會把對象的默認值清掉。java
@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)app
只須要在字段上面加上@Builder.Default註解便可ui
@Builder.Default private String aa = "zzzz";
咱們使用註解的方式,底層本質就是反射幫咱們生成了一系列的setter、getter,因此咱們直接打開編譯後的target包下面的.class文件,上面的全部緣由一目瞭然!
源文件:this
@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字節碼:code
// // 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字節碼文件查看具體代碼便知道了對象
好比上述第二點,採用@Builder的時候,這個aa並無默認值,因此會爲空!!get
public TestLombok.TestLombokBuilder aa(String aa) { this.aa = aa; return this; }
我的以爲若是想要使用@Builder,最簡單的方法就是直接寫上這4個註解,有默認值的話再加上@Builder.Default直接,正常狀況下就沒啥問題了!hash
@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); } }