lombok

Lombok簡介

Lombok是一個(gè)可以通過簡單的注解形式來幫助我們簡化消除一些必須有但顯得很臃腫的Java代碼的工具啃擦,通過使用對應(yīng)的注解既忆,可以在編譯源碼的時(shí)候生成對應(yīng)的方法。官方地址:https://projectlombok.org/咐容,github地址:https://github.com/rzwitserloot/lombok碍现。

IntelliJ IDEA 使用它的方法

  • 先安裝插件
Paste_Image.png
  • 然后引入lombok的jar包
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.14</version>
</dependency>

注解的介紹

官方注解介紹

  • @Getter and @Setter

    你可以用@Getter / @Setter注釋任何字段(當(dāng)然也可以注釋到類上的)士嚎,讓lombok自動生成默認(rèn)的getter / setter方法。
    默認(rèn)生成的方法是public的师倔,如果要修改方法修飾符可以設(shè)置AccessLevel的值构韵,例如:@Getter(access = AccessLevel.PROTECTED)

Paste_Image.png
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
public class User {
    @Getter(AccessLevel.PROTECTED) @Setter private Integer id;
    @Getter @Setter private String name;
    @Getter @Setter private String phone;
}
  • @ToString

    生成toString()方法,默認(rèn)情況下溯革,它會按順序(以逗號分隔)打印你的類名稱以及每個(gè)字段贞绳。可以這樣設(shè)置不包含哪些字段@ToString(exclude = "id") / @ToString(exclude = {"id","name"})
    如果繼承的有父類的話致稀,可以設(shè)置callSuper 讓其調(diào)用父類的toString()方法冈闭,例如:@ToString(callSuper = true)

import lombok.ToString;
@ToString(exclude = {"id","name"})
public class User {
  private Integer id;
  private String name;
  private String phone;
}

生成toString方法如下:

public String toString(){
  return "User(phone=" + phone + ")";
}
  • @EqualsAndHashCode

    生成hashCode()和equals()方法,默認(rèn)情況下抖单,它將使用所有非靜態(tài)萎攒,非transient字段。但可以通過在可選的exclude參數(shù)中來排除更多字段矛绘∷P荩或者,通過在parameter參數(shù)中命名它們來準(zhǔn)確指定希望使用哪些字段货矮。

@EqualsAndHashCode(exclude={"id", "shape"})
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 transient 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;
    }
  }
}

對比代碼如下:

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 transient 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;
   }
 }
}
  • @NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor

    @NoArgsConstructor生成一個(gè)無參構(gòu)造方法羊精。當(dāng)類中有final字段沒有被初始化時(shí),編譯器會報(bào)錯(cuò)囚玫,此時(shí)可用@NoArgsConstructor(force = true)喧锦,然后就會為沒有初始化的final字段設(shè)置默認(rèn)值 0 / false / null。對于具有約束的字段(例如@NonNull字段)抓督,不會生成檢查或分配燃少,因此請注意,正確初始化這些字段之前铃在,這些約束無效阵具。

import lombok.NoArgsConstructor;
import lombok.NonNull;
@NoArgsConstructor(force = true)
public class User {
    @NonNull private Integer id;
    @NonNull private String name;
    private final String phone ;
}

@RequiredArgsConstructor會生成構(gòu)造方法(可能帶參數(shù)也可能不帶參數(shù)),如果帶參數(shù)定铜,這參數(shù)只能是以final修飾的未經(jīng)初始化的字段阳液,或者是以@NonNull注解的未經(jīng)初始化的字段
@RequiredArgsConstructor(staticName = "of")會生成一個(gè)of()的靜態(tài)方法,并把構(gòu)造方法設(shè)置為私有的

Paste_Image.png

Paste_Image.png
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class User {
  @NonNull private Integer id ;
  @NonNull private String name = "bbbb";
  private final String phone;
}
//另外一個(gè)
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor(staticName = "of")
public class User {
  @NonNull private Integer id ;
  @NonNull private String name = "bbbb";
  private final String phone;
}

@AllArgsConstructor 生成一個(gè)全參數(shù)的構(gòu)造方法

Paste_Image.png
import lombok.AllArgsConstructor;
import lombok.NonNull;
@AllArgsConstructor
public class User {
  @NonNull private Integer id ;
  @NonNull private String name = "bbbb";
  private final String phone;
}
  • @Data

    @Data 包含了 @ToString揣炕、@EqualsAndHashCode趁舀、@Getter / @Setter和@RequiredArgsConstructor的功能

  • @Accessors

    @Accessors 主要用于控制生成的getter和setter
    主要參數(shù)介紹

    • fluent boolean值,默認(rèn)為false祝沸。此字段主要為控制生成的getter和setter方法前面是否帶get/set
    • chain boolean值矮烹,默認(rèn)false越庇。如果設(shè)置為true,setter返回的是此對象奉狈,方便鏈?zhǔn)秸{(diào)用方法
    • prefix 設(shè)置前綴 例如:@Accessors(prefix = "abc") private String abcAge 當(dāng)生成get/set方法時(shí)卤唉,會把此前綴去掉
    Paste_Image.png
  • @Synchronized

    給方法加上同步鎖

import lombok.Synchronized;
public class SynchronizedExample {
   private final Object readLock = new Object();
   
  @Synchronized
  public static void hello() {
    System.out.println("world");
  }
   
  @Synchronized
  public int answerToLife() {
    return 42;
 }
  @Synchronized("readLock")
  public void foo() {
    System.out.println("bar");
   }
}
//等效代碼
public class SynchronizedExample {
private static final Object $LOCK = new Object[0];
private final Object $lock = new Object[0];
private final Object readLock = new Object();
 
public static void hello() {
  synchronized($LOCK) {
    System.out.println("world");
  }
}
 
public int answerToLife() {
 synchronized($lock) {
    return 42;
  }
}

public void foo() {
  synchronized(readLock) {
    System.out.println("bar");
  }
}
}
  • @Wither

    提供了給final字段賦值的一種方法

//使用lombok注解的
import lombok.AccessLevel;
import lombok.NonNull;
import lombok.experimental.Wither;
public class WitherExample {
  @Wither private final int age;
  @Wither(AccessLevel.PROTECTED) @NonNull private final String name;
   
  public WitherExample(String name, int age) {
    if (name == null) throw new NullPointerException();
    this.name = name;
    this.age = age;
  }
}
//等效代碼
import lombok.NonNull;
public class WitherExample {
private final int age;
private @NonNull final String name;

public WitherExample(String name, int age) {
 if (name == null) throw new NullPointerException();
 this.name = name;
 this.age = age;
}

public WitherExample withAge(int age) {
 return this.age == age ? this : new WitherExample(age, name);
}

protected WitherExample withName(@NonNull String name) {
 if (name == null) throw new java.lang.NullPointerException("name");
 return this.name == name ? this : new WitherExample(age, name);
}
}
  • @onX

    在注解里面添加注解的方式

直接看代碼

public class SchoolDownloadLimit implements Serializable {
    private static final long serialVersionUID = -196412797757026250L;

    @Getter(onMethod = @_({@Id,@Column(name="id",nullable=false),@GeneratedValue(strategy= GenerationType.AUTO)}))
    @Setter
    private Integer id;

    @Getter(onMethod = @_(@Column(name="school_id")))
    @Setter
    private Integer schoolId;


    @Getter(onMethod = @_(@Column(name = "per_download_times")))
    @Setter
    private Integer perDownloadTimes;

    @Getter(onMethod = @_(@Column(name = "limit_time")))
    @Setter
    private Integer limitTime;

    @Getter(onMethod = @_(@Column(name = "download_to_limit_an_hour")))
    @Setter
    private Integer downloadToLimitInHour;

    @Getter(onMethod = @_(@Column(name = "available")))
    @Setter
    private Integer available = 1;
}
  • @Builder

    @Builder注釋為你的類生成復(fù)雜的構(gòu)建器API。
    lets you automatically produce the code required to have your class be instantiable with code such as:

Person.builder().name("Adam Savage").city("San Francisco").job("Mythbusters").job("Unchained Reaction").build();

直接看官方示例仁期,對比一下就都明白了

//使用lombok注解的
import lombok.Builder;
import lombok.Singular;
import java.util.Set;
@Builder
public class BuilderExample {
 private String name;
 private int age;
 @Singular private Set<String> occupations;
}
//等效代碼
import java.util.Set;
class BuilderExample {
  private String name;
  private int age;
  private Set<String> occupations;

  BuilderExample(String name, int age, Set<String> occupations) {
      this.name = name;
      this.age = age;
      this.occupations = occupations;
  }

  public static BuilderExampleBuilder builder() {
      return new BuilderExampleBuilder();
  }

  public static class BuilderExampleBuilder {
      private String name;
      private int age;
      private java.util.ArrayList<String> occupations;

      BuilderExampleBuilder() {
      }

      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<String>();
          }

          this.occupations.add(occupation);
          return this;
      }

      public BuilderExampleBuilder occupations(Collection<? extends String> occupations) {
          if (this.occupations == null) {
              this.occupations = new java.util.ArrayList<String>();
          }

          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.
          // go to https://projectlombok.org/features/Singular-snippet.html to see it.
          Set<String> occupations = ...;
          return new BuilderExample(name, age, occupations);
      }

      @java.lang.Override
      public String toString() {
          return "BuilderExample.BuilderExampleBuilder(name = " + this.name + ", age = " + this.age + ", occupations = " + this.occupations + ")";
      }
  }
}
  • @Delegate

    這個(gè)注解也是相當(dāng)?shù)呐1粕G聪旅娴慕貓D,它會該類生成一些列的方法跛蛋,這些方法都來自與List接口

    Paste_Image.png

附帶一個(gè)我使用的例子
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.Date;

@Entity
@Table(name= Constants.TABLE_SCHOOL_DOWNLOAD_LIMIT)
@RequiredArgsConstructor(staticName = "of")
@Accessors(chain = true)
@ToString
public class SchoolDownloadLimit implements Serializable {
    private static final long serialVersionUID = -196412797757026250L;

    @Getter(onMethod = @_({@Id,@Column(name="id",nullable=false),@GeneratedValue(strategy= GenerationType.AUTO)}))
    @Setter
    private Integer id;

    @Getter(onMethod = @_(@Column(name="school_id")))
    @Setter
    private Integer schoolId;

    @Getter(onMethod = @_(@Column(name = "per_download_times")))
    @Setter
    private Integer perDownloadTimes;

    @Getter(onMethod = @_(@Column(name = "limit_time")))
    @Setter
    private Integer limitTime;

    @Getter(onMethod = @_(@Column(name = "download_to_limit_an_hour")))
    @Setter
    private Integer downloadToLimitInHour;

    @Getter(onMethod = @_(@Column(name = "available")))
    @Setter
    private Integer available = 1;

    @Getter(onMethod = @_(@Column(name = "create_time")))
    @Setter
    private Date createTime;

    @Getter(onMethod = @_(@Column(name = "update_time")))
    @Setter
    private Date updateTime;
}

就介紹這么多了熬的,更多的注解請看官方文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市赊级,隨后出現(xiàn)的幾起案子押框,更是在濱河造成了極大的恐慌,老刑警劉巖理逊,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件橡伞,死亡現(xiàn)場離奇詭異,居然都是意外死亡晋被,警方通過查閱死者的電腦和手機(jī)兑徘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來羡洛,“玉大人挂脑,你說我怎么就攤上這事∮辏” “怎么了最域?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長锈麸。 經(jīng)常有香客問我,道長牺蹄,這世上最難降的妖魔是什么忘伞? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮沙兰,結(jié)果婚禮上氓奈,老公的妹妹穿的比我還像新娘。我一直安慰自己鼎天,他們只是感情好舀奶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著斋射,像睡著了一般育勺。 火紅的嫁衣襯著肌膚如雪但荤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天涧至,我揣著相機(jī)與錄音腹躁,去河邊找鬼。 笑死南蓬,一個(gè)胖子當(dāng)著我的面吹牛纺非,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赘方,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼烧颖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了窄陡?” 一聲冷哼從身側(cè)響起炕淮,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泳梆,沒想到半個(gè)月后鳖悠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡优妙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年乘综,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片套硼。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡卡辰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出邪意,到底是詐尸還是另有隱情九妈,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布雾鬼,位于F島的核電站萌朱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏策菜。R本人自食惡果不足惜晶疼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望又憨。 院中可真熱鬧翠霍,春花似錦、人聲如沸蠢莺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽躏将。三九已至锄弱,卻和暖如春考蕾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背棵癣。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工辕翰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人狈谊。 一個(gè)月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓喜命,卻偏偏與公主長得像,于是被迫代替她去往敵國和親河劝。 傳聞我的和親對象是個(gè)殘疾皇子壁榕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)赎瞎,斷路器牌里,智...
    卡卡羅2017閱讀 134,659評論 18 139
  • Lombok介紹及使用方法 lombok簡介lombok是一個(gè)非常好用的小工具,剛見到的時(shí)候就感覺非常驚艷务甥,有一種...
    開發(fā)者阿俊閱讀 759評論 0 1
  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗(yàn)牡辽。 張土汪:刷leetcod...
    土汪閱讀 12,747評論 0 33
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法敞临,內(nèi)部類的語法态辛,繼承相關(guān)的語法,異常的語法挺尿,線程的語...
    子非魚_t_閱讀 31,639評論 18 399
  • 一奏黑、 1、請用Java寫一個(gè)冒泡排序方法 【參考答案】 public static void Bubble(int...
    獨(dú)云閱讀 1,375評論 0 6