史上最全面的Lombok 註解介紹,Look 一下吧!

文章推薦指數: 80 %
投票人數:10人

public class GetterSetterExample { @Getter @Setter private int age = 10; @Setter(AccessLevel.PROTECTED) private String name; @Override MdEditor 史上最全面的Lombok註解介紹,Look一下吧! 語言:CN/TW/HK 時間 2020-11-1616:01:28 afreon 主題: java spring 大咖揭祕Java人都栽在了哪?點選免費領取《大廠面試清單》,攻克面試難關~>>> 一、@Getterand@Setter 使用@Getter和/或@Setter註釋任何欄位,以使lombok自動生成預設的getter/setter。

預設的getter只是返回該欄位,如果該欄位被稱為foo,則名為getFoo(如果該欄位的型別為boolean,則為isFoo)。

預設生成的 getter/setter方法是公共的,除非你明確指定一個AccessLevel。

合法訪問級別為PUBLIC,PROTECTED,PACKAGE和PRIVATE。

你還可以在類上新增@Getter和/或@Setter註釋。

在這種情況下,就好像你使用該註釋來註釋該類中的所有非靜態欄位一樣。

你始終可以使用特殊的AccessLevel.NONE訪問級別來手動禁用任何欄位的getter/setter生成。

這使你可以覆蓋類上的@Getter,@Setter或@Data註釋的行為。

WithLombok: import lombok.AccessLevel;import lombok.Getter;import lombok.Setter;public class GetterSetterExample {    @Getter   @Setter   private int age = 10;    @Setter(AccessLevel.PROTECTED)   private String name;    @Override   public String toString() {    return String.format("%s (age: %d)", name, age);  }} NativeJava: public class GetterSetterExample {  private int age = 10;  private String name;    @Override   public String toString() {    return String.format("%s (age: %d)", name, age);  }    public int getAge() {    return age;  }    public void setAge(int age) {    this.age = age;  }    protected void setName(String name) {    this.name = name;  }} 二、@ToString 任何類定義都可以使用@ToString註釋,以使lombok生成toString()方法的實現。

預設情況下,將列印所有非靜態欄位。

如果要跳過某些欄位,可以使用@ToString.Exclude註釋這些欄位。

或者,可以通過使用@ToString(onlyExplicitlyIncluded=true),然後使用@ToString.Include標記要包含的每個欄位,來確切指定希望使用的欄位。

通過將callSuper設定為true,可以將toString的超類實現的輸出包含到輸出中。

請注意,java.lang.Object中toString() 的預設實現幾乎毫無意義。

WithLombok: import lombok.ToString;@ToStringpublic class ToStringExample {  private static final int STATIC_VAR = 10;  private String name;  private Shape shape = new Square(5, 10);  private String[] tags;  @ToString.Exclude   private int id;    public String getName() {    return this.name;  }    @ToString(callSuper=true, includeFieldNames=true)  public static class Square extends Shape {    private final int width, height;        public Square(int width, int height) {      this.width = width;      this.height = height;    }  }} NativeJava: import java.util.Arrays;public class ToStringExample {  private static final int STATIC_VAR = 10;  private String name;  private Shape shape = new Square(5, 10);  private String[] tags;  private int id;    public String getName() {    return this.name;  }    public static class Square extends Shape {    private final int width, height;        public Square(int width, int height) {      this.width = width;      this.height = height;    }        @Override     public String toString() {      return "Square(super=" + super.toString() + ", width=" + this.width + ", height=" + this.height + ")";    }  }    @Override   public String toString() {    return "ToStringExample(" + this.getName() + ", " + this.shape + ", " + Arrays.deepToString(this.tags) + ")";  }} 三、@EqualsAndHashCode 任何類定義都可以使用@EqualsAndHashCode進行註釋,以使lombok生成equals(Objectother)和hashCode()方法的實現。

預設情況下,它將使用所有非靜態,非瞬態欄位,但是您可以通過使用@EqualsAndHashCode.Include標記型別成員來修改使用哪些欄位(甚至指定要使用各種方法的輸出)。

 @EqualsAndHashCode.Exclude。

或者,可以通過使用@ EqualsAndHashCode.Include標記並使用@EqualsAndHashCode(onlyExplicitlyIncluded=true)來精確指定要使用的欄位或方法。

如果將@EqualsAndHashCode應用於擴充套件另一個類的類,則此功能會有些棘手。

通常,為此類自動生成equals和hashCode方法是一個壞主意,因為超類還定義了欄位,該欄位也需要equals/hashCode程式碼,但不會生成此程式碼。

通過將callSuper設定為true,可以在生成的方法中包括超類的equals和hashCode方法。

WithLombok: import lombok.EqualsAndHashCode;@EqualsAndHashCodepublic class EqualsAndHashCodeExample {  private transient int transientVar = 10;  private String name;  private double score;  @EqualsAndHashCode.Exclude   private Shape shape = new Square(5, 10);  private String[] tags;  @EqualsAndHashCode.Exclude   private int id;    public String getName() {    return this.name;  }    @EqualsAndHashCode(callSuper=true)  public static class Square extends Shape {    private final int width, height;        public Square(int width, int height) {      this.width = width;      this.height = height;    }  }} NativeJava: import java.util.Arrays;public class EqualsAndHashCodeExample {  private transient int transientVar = 10;  private String name;  private double score;  private Shape shape = new Square(5, 10);  private String[] tags;  private int id;    public String getName() {    return this.name;  }    @Override   public boolean equals(Object o) {    if (o == this) return true;    if (!(o instanceof EqualsAndHashCodeExample)) return false;    EqualsAndHashCodeExample other = (EqualsAndHashCodeExample) o;    if (!other.canEqual((Object)this)) return false;    if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;    if (Double.compare(this.score, other.score) != 0) return false;    if (!Arrays.deepEquals(this.tags, other.tags)) return false;    return true;  }    @Override   public int hashCode() {    final int PRIME = 59;    int result = 1;    final long temp1 = Double.doubleToLongBits(this.score);    result = (result*PRIME) + (this.name == null ? 43 : this.name.hashCode());    result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));    result = (result*PRIME) + Arrays.deepHashCode(this.tags);    return result;  }    protected boolean canEqual(Object other) {    return other instanceof EqualsAndHashCodeExample;  }    public static class Square extends Shape {    private final int width, height;        public Square(int width, int height) {      this.width = width;      this.height = height;    }        @Override     public boolean equals(Object o) {      if (o == this) return true;      if (!(o instanceof Square)) return false;      Square other = (Square) o;      if (!other.canEqual((Object)this)) return false;      if (!super.equals(o)) return false;      if (this.width != other.width) return false;      if (this.height != other.height) return false;      return true;    }        @Override     public int hashCode() {      final int PRIME = 59;      int result = 1;      result = (result*PRIME) + super.hashCode();      result = (result*PRIME) + this.width;      result = (result*PRIME) + this.height;      return result;    }        protected boolean canEqual(Object other) {      return other instanceof Square;    }  }} 四、@AllArgsConstructor @RequiredArgsConstructor @NoArgsConstructor @NoArgsConstructor將生成沒有引數的建構函式。

如果欄位由final修飾,則將導致編譯器錯誤,除非使用@NoArgsConstructor(force=true),否則所有final欄位都將初始化為0/false/null。

對於具有約束的欄位(例如@NonNull欄位),不會生成任何檢查。

@RequiredArgsConstructor為每個需要特殊處理的欄位生成一個帶有1個引數的建構函式。

所有未初始化的final欄位都會獲取一個引數,以及所有未宣告其位置的未標記為@NonNull的欄位。

@AllArgsConstructor為類中的每個欄位生成一個帶有1個引數的建構函式。

標有@NonNull的欄位將對這些引數進行空檢查。

WithLombok: import lombok.AccessLevel;import lombok.RequiredArgsConstructor;import lombok.AllArgsConstructor;import lombok.NonNull;@RequiredArgsConstructor(staticName = "of")@AllArgsConstructor(access = AccessLevel.PROTECTED)public class ConstructorExample {  private int x, y;  @NonNull   private T description;    @NoArgsConstructor  public static class NoArgsExample {    @NonNull     private String field;  }} NativeJava: public class ConstructorExample {  private int x, y;  @NonNull   private T description;    private ConstructorExample(T description) {    if (description == null) throw new NullPointerException("description");    this.description = description;  }    public static  ConstructorExample of(T description) {    return new ConstructorExample(description);  }    @java.beans.ConstructorProperties({"x", "y", "description"})  protected ConstructorExample(int x, int y, T description) {    if (description == null) throw new NullPointerException("description");    this.x = x;    this.y = y;    this.description = description;  }    public static class NoArgsExample {    @NonNull     private String field;        public NoArgsExample() {    }  }} 五、@Data @Data是一個方便的快捷方式批註,它將@ToString,@EqualsAndHashCode,@Getter/@Setter和@RequiredArgsConstructor的功能捆綁在一起:換句話說,@Data生成通常與簡單POJO關聯的所有樣板(普通的舊Java物件)和bean:所有欄位的getter,所有非final欄位的setter,以及涉及類欄位的適當的toString,equals和hashCode實現,以及初始化所有final欄位以及所有非final欄位的建構函式沒有使用@NonNull標記的初始化程式,以確保該欄位永遠不會為null。

WithLombok: import lombok.AccessLevel;import lombok.Setter;import lombok.Data;import lombok.ToString;@Data public class DataExample {  private final String name;  @Setter(AccessLevel.PACKAGE)   private int age;  private double score;  private String[] tags;    @ToString(includeFieldNames=true)  @Data(staticConstructor="of")  public static class Exercise {    private final String name;    private final T value;  }} NativeJava: import java.util.Arrays;public class DataExample {  private final String name;  private int age;  private double score;  private String[] tags;    public DataExample(String name) {    this.name = name;  }    public String getName() {    return this.name;  }    void setAge(int age) {    this.age = age;  }    public int getAge() {    return this.age;  }    public void setScore(double score) {    this.score = score;  }    public double getScore() {    return this.score;  }    public String[] getTags() {    return this.tags;  }    public void setTags(String[] tags) {    this.tags = tags;  }    @Override   public String toString() {    return "DataExample(" + this.getName() + ", " + this.getAge() + ", " + this.getScore() + ", " + Arrays.deepToString(this.getTags()) + ")";  }    protected boolean canEqual(Object other) {    return other instanceof DataExample;  }    @Override   public boolean equals(Object o) {    if (o == this) return true;    if (!(o instanceof DataExample)) return false;    DataExample other = (DataExample) o;    if (!other.canEqual((Object)this)) return false;    if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;    if (this.getAge() != other.getAge()) return false;    if (Double.compare(this.getScore(), other.getScore()) != 0) return false;    if (!Arrays.deepEquals(this.getTags(), other.getTags())) return false;    return true;  }    @Override   public int hashCode() {    final int PRIME = 59;    int result = 1;    final long temp1 = Double.doubleToLongBits(this.getScore());    result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());    result = (result*PRIME) + this.getAge();    result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));    result = (result*PRIME) + Arrays.deepHashCode(this.getTags());    return result;  }    public static class Exercise {    private final String name;    private final T value;        private Exercise(String name, T value) {      this.name = name;      this.value = value;    }        public static  Exercise of(String name, T value) {      return new Exercise(name, value);    }        public String getName() {      return this.name;    }        public T getValue() {      return this.value;    }        @Override     public String toString() {      return "Exercise(name=" + this.getName() + ", value=" + this.getValue() + ")";    }        protected boolean canEqual(Object other) {      return other instanceof Exercise;    }        @Override     public boolean equals(Object o) {      if (o == this) return true;      if (!(o instanceof Exercise)) return false;      Exercise> other = (Exercise>) o;      if (!other.canEqual((Object)this)) return false;      if (this.getName() == null ? other.getValue() != null : !this.getName().equals(other.getName())) return false;      if (this.getValue() == null ? other.getValue() != null : !this.getValue().equals(other.getValue())) return false;      return true;    }        @Override     public int hashCode() {      final int PRIME = 59;      int result = 1;      result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());      result = (result*PRIME) + (this.getValue() == null ? 43 : this.getValue().hashCode());      return result;    }  }} 六、@Value @Value註解和@Data類似,區別在於它會把所有成員變數預設定義為privatefinal修飾,並且不會生成set方法。

七、@Builder 構建者模式 只能標註到類上,將生成類的一個當前流程的一種鏈式構造工廠,如下: User buildUser = User.builder().username("riemann").password("123").build(); 可配合@Singular註解使用,@Singular註解使用在jdk內部集合型別的屬性,Map型別的屬性以及Guava的com.google.common.collect 的屬性上。

例如未標註@Singular的屬性,一般setter時,會直接覆蓋原來的引用,標註了@Singular的屬性,集合屬性支援新增操作,會在屬性原來的基礎上增加。

WithLombok: import lombok.Builder;import lombok.Singular;import java.util.Set;@Builderpublic class BuilderExample {  @Builder.Default   private long created = System.currentTimeMillis();  private String name;  private int age;  @Singular   private Set occupations;} NativeJava: import java.util.Set;public class BuilderExample {  private long created;  private String name;  private int age;  private Set occupations;    BuilderExample(String name, int age, Set occupations) {    this.name = name;    this.age = age;    this.occupations = occupations;  }    private static long $default$created() {    return System.currentTimeMillis();  }    public static BuilderExampleBuilder builder() {    return new BuilderExampleBuilder();  }    public static class BuilderExampleBuilder {    private long created;    private boolean created$set;    private String name;    private int age;    private java.util.ArrayList occupations;        BuilderExampleBuilder() {    }        public BuilderExampleBuilder created(long created) {      this.created = created;      this.created$set = true;      return this;    }        public BuilderExampleBuilder name(String name) {      this.name = name;      return this;    }        public BuilderExampleBuilder age(int age) {      this.age = age;      return this;    }        public BuilderExampleBuilder occupation(String occupation) {      if (this.occupations == null) {        this.occupations = new java.util.ArrayList();      }            this.occupations.add(occupation);      return this;    }        public BuilderExampleBuilder occupations(Collection extends String> occupations) {      if (this.occupations == null) {        this.occupations = new java.util.ArrayList();      }      this.occupations.addAll(occupations);      return this;    }        public BuilderExampleBuilder clearOccupations() {      if (this.occupations != null) {        this.occupations.clear();      }            return this;    }    public BuilderExample build() {      // complicated switch statement to produce a compact properly sized immutable set omitted.      Set occupations = ...;      return new BuilderExample(created$set ? created : BuilderExample.$default$created(), name, age, occupations);    }        @java.lang.Override    public String toString() {      return "BuilderExample.BuilderExampleBuilder(created = " + this.created + ", name = " + this.name + ", age = " + this.age + ", occupations = " + this.occupations + ")";    }  }} 八、@Accessors 鏈式風格 @Accessors批註用於配置lombok如何生成和查詢getter和setter。

預設情況下,lombok遵循針對getter和setter的bean規範:例如,名為Pepper的欄位的getter是getPepper。

但是,有些人可能希望打破bean規範,以得到更好看的API。

 @Accessors允許您執行此操作。

可標註在類或屬性上,當然最實用的功能還是標註到類上。

標註到類上,chain屬性設定為true時,類的所有屬性的setter方法返回值將為this,用來支援setter方法的鏈式寫法。

如: new User().setUsername("riemann").setPassword("123"); fluent屬性設定為true時,類的所有getter,setter方法將省略get和set字首,獲取屬性值直接使用屬性名相同的無參方法,設定屬性值使用屬性名相同的有參方法,並且返回值為this。

如: User user = new User().username("riemann").password("123");String username = user.username();String password = user.password(); 標註到屬性上,使用prefix設定需要省略的屬性生成getter,setter方法時的字首,且屬性必須為駝峰式命名。

@Accessors(prefix = "r")@Getter@Setterprivate String rUsername = "riemann"; 編譯之後為 public String getUsername() {    return rUsername;}public void setUsername(String rUsername) {    this.rUsername = rUsername;} 九、@Slf4jand@Log4j 在需要列印日誌的類中使用,專案中使用slf4j、log4j日誌框架 十、@NonNull 該註解快速判斷是否為空,為空丟擲java.lang.NullPointerException。

十一、@Synchronized 註解自動新增到同步機制,生成的程式碼並不是直接鎖方法,而是鎖程式碼塊,作用範圍是方法上。

十二、@Cleanup 註解用於確保已分配的資源被釋放(IO的連線關閉)。

作者:riemann_ blog.csdn.net/riemann_/article/details/105374987 往期精選   點選標題可跳轉 關於Java你可能不知道的那些事之Java註解和反射 IntellijIDEA使用 Groovy指令碼一鍵生成帶註解的實體類詳細步驟 SpringCloud實戰系列之Zuul微服務閘道器搭建及配置 Spring原始碼分析(四)容器的基礎XmlBeanFactory(系列文章基於Spring5.0) Spring原始碼分析(三)容器核心類(系列文章基於Spring5.0) Spring原始碼分析(二)容器基本用法(系列文章基於Spring5.0) Spring原始碼分析(一)從基本介紹開始(系列文章基於Spring5.0) 微軟公司將不相容IE的網站自動重定向至Edge瀏覽器 面試官問:MyBatis日誌如何做到相容所有常用的日誌框架? 為什麼很多公司強制棄坑Fastjson了?主推Jackson 點個贊,就知道你“在看”! 本文分享自微信公眾號-Java精選(w_z90110)。

如有侵權,請聯絡[email protected]刪除。

本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

「其他文章」 Linux安裝MySQL8.0.26超詳細圖文步驟 各大廠面試整理20道Java後端開發面試題總結 GitHub和Gitee開源免費10個超讚後臺管理面板,看完驚呆了 【079期】面試官:設計一個安全的登入都要考慮哪些?我一臉懵逼。



【077期】面試官問:談談你對Java執行緒安全與不安全的理解和看法? SpringBoot從入門到精通(十一)整合Swagger框架,實現自動生成介面文件 【072期】面試官:對併發熟悉嗎?說說wait、notify、yield等執行緒間的協作 利用註解反射優雅的實現通用Excel匯入匯出(通用版附原始碼) SpringCloud從入門到精通(二)整合Nacos構建微服務實現服務註冊 【066期】面試官問:說一下Java反射機制有哪些應用場景? 2021年面試,整理全網初、中、高階常見Java面試題 關於Session會話深入探討 史上最全面的Lombok註解介紹,Look一下吧! IntellijIDEA使用Groovy指令碼一鍵生成帶註解的實體類詳細步驟 「java」 Java多執行緒併發資料錯亂了,介面冪等性如何設計? 簡單聊聊MySQL中的六種日誌 Java810=Java18 Java近期新聞:JDK19與JakartaEE10的更新以及AmazonCorretto的非同步、緩衝日誌 Java多執行緒【三種實現方法】 NGINX助力緩解log4j漏洞(CVE-2021-44228) Java學多久可以找到高薪工作 Java程式碼執行順序-順口溜 大資料分散式計算系統Spark入門核心之RDD 關於Java18你想知道的一切 「spring」 厲害!我帶的實習生僅用四步就整合SpringSecurityJWT實現登入認證! 淺談SpringBoot載入配置檔案的實現方式,通俗易懂! 基於SpringCache實現二級快取(CaffeineRedis) Java系列|遠端熱部署在美團的落地實踐 SpringMVC工作流程--通透較詳細 SpingSecurity-動態認證使用者資訊 淺談Shiro框架在SpringBoot中的認證應用 我聽候選人的,在B站看了十幾個小時的影片 詳解4種微服務框架接入Istio方案 原始碼角度,分析@Transactional實現原理



請為這篇文章評分?