lombok的@Builder實際是建造者模式的一個變種,所以在創建復雜對象時常使用
這里對lombok的@Builder和@Data組合的使用示例
import lombok.Builder; import lombok.Data; @Data @Builder public class People { private String name; private String sex; private int age; }
使用了@Bulider和@Data注解后,就可以使用鏈式風格優雅地創建對象
public class TestLombok { @Test public void testBuilderAnnotation(){ People luoTianyan = People.builder() .sex("female") .age(23) .name("LuoTianyan") .build(); System.out.println(luoTianyan.toString()); //People(name=LuoTianyan, sex=female, age=23) People people = new People("LuoTianyan","female",23); System.out.println(luoTianyan.equals(people)); //true } }
class People加上了@Builder和@Data注解后,多了一個靜態內部類PeopleBuilder,People調用靜態方法builder生成PeopleBuilder對象,PeopleBuilder對象可以使用".屬性名(屬性值)"的方式進行屬性設置,再調用build()方法就生成了People對象,並且如果兩個People對象的屬性如果相同,就會認為這兩個對象相等,即重寫了hashCode和equls方法。
這里就直接在Intellij IDEA下,查看反編譯的文件People.class;
可以看到,生成的有:
- Getter和Setter方法;
- 訪問類型是private無參構造方法,訪問類型為default的全部參數的構造方法;
- 重寫hashCode、equals、toString方法,則People可以做為Map的key;
- 訪問類型為public的靜態方法builder,返回的是People.PeopleBuilder對象,非單例;
- 訪問類型為public的靜態內部類PeopleBuilder,該類主要有build方法,返回類型是People;
- 最后還有個canEqual方法,判斷是否與People同類型。
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // public class People { private String name; private String sex; private int age; People(String name, String sex, int age) { this.name = name; this.sex = sex; this.age = age; } public static People.PeopleBuilder builder() { return new People.PeopleBuilder(); } private People() { } public String getName() { return this.name; } public String getSex() { return this.sex; } public int getAge() { return this.age; } public void setName(String name) { this.name = name; } public void setSex(String sex) { this.sex = sex; } public void setAge(int age) { this.age = age; } public boolean equals(Object o) { if (o == this) { return true; } else if (!(o instanceof People)) { return false; } else { People other = (People)o; if (!other.canEqual(this)) { return false; } else { label39: { Object this$name = this.getName(); Object other$name = other.getName(); if (this$name == null) { if (other$name == null) { break label39; } } else if (this$name.equals(other$name)) { break label39; } return false; } Object this$sex = this.getSex(); Object other$sex = other.getSex(); if (this$sex == null) { if (other$sex != null) { return false; } } else if (!this$sex.equals(other$sex)) { return false; } if (this.getAge() != other.getAge()) { return false; } else { return true; } } } } protected boolean canEqual(Object other) { return other instanceof People; } public int hashCode() { int PRIME = true; int result = 1; Object $name = this.getName(); int result = result * 59 + ($name == null ? 43 : $name.hashCode()); Object $sex = this.getSex(); result = result * 59 + ($sex == null ? 43 : $sex.hashCode()); result = result * 59 + this.getAge(); return result; } public String toString() { return "People(name=" + this.getName() + ", sex=" + this.getSex() + ", age=" + this.getAge() + ")"; } public static class PeopleBuilder { private String name; private String sex; private int age; PeopleBuilder() { } public People.PeopleBuilder name(String name) { this.name = name; return this; } public People.PeopleBuilder sex(String sex) { this.sex = sex; return this; } public People.PeopleBuilder age(int age) { this.age = age; return this; } public People build() { return new People(this.name, this.sex, this.age); } public String toString() { return "People.PeopleBuilder(name=" + this.name + ", sex=" + this.sex + ", age=" + this.age + ")"; } } }
自從Java 6起,Javac就支持“JSR 269 Pluggable Annotation Processing API”規范,只要程序實現了該API,就能在javac運行的時候得到調用。
Lombok就是一個實現了"JSR 269 API"的程序。在使用javac的過程中,它產生作用的具體流程如下:
-
Javac對源代碼進行分析,生成一棵抽象語法樹(AST)
-
Javac編譯過程中調用實現了JSR 269的Lombok程序
-
此時Lombok就對第一步驟得到的AST進行處理,找到Lombok注解所在類對應的語法樹(AST),然后修改該語法樹(AST),增加Lombok注解定義的相應樹節點
-
Javac使用修改后的抽象語法樹(AST)生成字節碼文件
