Lombok簡介
Lombok是一個(gè)可以通過簡單的注解形式來幫助我們簡化消除一些必須有但顯得很臃腫的Java代碼的工具啃擦,通過使用對應(yīng)的注解既忆,可以在編譯源碼的時(shí)候生成對應(yīng)的方法。官方地址:https://projectlombok.org/咐容,github地址:https://github.com/rzwitserloot/lombok碍现。
IntelliJ IDEA 使用它的方法
- 先安裝插件
- 然后引入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)
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è)置為私有的
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)造方法
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;
}