關(guān)于Lombok簡(jiǎn)化編碼使用及說(shuō)明
1.Lombok介紹以及其它簡(jiǎn)介
1.1 介紹
Lombok是一個(gè)通過(guò)注解的形式或簡(jiǎn)單關(guān)鍵字簡(jiǎn)化和消除Java應(yīng)用程序中一些必須但是重復(fù)或顯得臃腫的樣板代碼的實(shí)用工具,使用Lombok會(huì)在編譯階段根據(jù)相應(yīng)的注解生成對(duì)應(yīng)的字節(jié)碼,使編譯前的源碼看起來(lái)更加簡(jiǎn)潔,但功能不變。
其特征可參見(jiàn)官網(wǎng)
1.2 優(yōu)點(diǎn)
優(yōu)點(diǎn)有很多,這里主要列舉自己認(rèn)為重要的
- 提高編碼效率
- 使代碼更簡(jiǎn)潔
- 消除冗長(zhǎng)代碼
- 避免修改字段名字時(shí)忘記修改方法名
1.3 原理
1.為什么能使用Lombok?
Lombok支持JSR 269 Pluggable Annotation Processing API,Javac從Java6開(kāi)始支持“JSR 269 API”規(guī)范,只要程序?qū)崿F(xiàn)了該API,就能在Javac運(yùn)行的時(shí)候得到調(diào)用
2.Javac編譯源碼的具體流程如下:

1.4 安裝
Lombok需要通過(guò)插件的形式與IDE集成,如果使用IntelliJ IDEA可直接到插件倉(cāng)庫(kù)搜索Lombok進(jìn)行安裝,最后重啟IDEA。
如圖:

1.5 類構(gòu)造
| 注解(位置TYPE)/屬性 | staticName私有化生產(chǎn)的構(gòu)造器并生成一個(gè)靜態(tài)構(gòu)造方法 | onConstructor在生成的構(gòu)造器上增加其他注解 | access設(shè)置生成的構(gòu)造器的可見(jiàn)性 | force為true時(shí),初始化所有靜態(tài)屬性到0/false/null |
|---|---|---|---|---|
| @AllArgsConstructor生成一個(gè)全參構(gòu)造器 | √ | √ | √ | |
| @RequiredArgsConstructor生成一個(gè)必要參數(shù)構(gòu)造器 | √ | √ | √ | |
| @NoArgsConstructor生成一個(gè)空參構(gòu)造器 | √ | √ | √ | √ |
| 注解(位置) | 屬性 |
|---|---|
| @Builder(TYPE,METHOD, CONSTRUCTOR)生成目標(biāo)類的一個(gè)建造者內(nèi)部類 | builderClassName:自定義建造類 (TypeName)Builder 的類名builderMethodName:自定義 builder() 的方法名buildMethodName:自定義 build() 的方法名toBuilder: |
| @Builder.ObtainVia(FIELD,PARAMETER)注明一個(gè)參數(shù)或?qū)傩缘墨@取方式 | field:使用 this.field 賦值method:使用this.method() 賦值isStatic:使用 SelfType.method(this) 賦值,要求 mthod 是靜態(tài)的 |
| @Builder.Default(FIELD)注明一個(gè)屬性有默認(rèn)值 | |
| @Singular(FIELD,PARAMETER)允許為集合類型的屬性一項(xiàng)一項(xiàng)賦值 | value:?jiǎn)雾?xiàng)賦值方法的方法名 |
1.6 類屬性
| 注解(位置) | 屬性 |
|---|---|
| @Getter(TYPE,FIELD)自動(dòng)生成標(biāo)準(zhǔn)的getter方法 | lazy:默認(rèn)false,不可用onMethod:在方法上增加其他注解value:設(shè)置方法的可見(jiàn)性 |
| @Setter(TYPE,FIELD)自動(dòng)生成標(biāo)準(zhǔn)的setter方法 | onParam:在方法參數(shù)上增加其他注解onMethod:同@Getter.onMethodvalue:同@Getter.value |
| @Data(TYPE)@Getter/@Setter,@ToString, @EqualsAndHashCode和@RequiredArgsConstructor 組合的便捷寫法 | staticConstructor:同@RequiredArgsConstructor.staticName |
| @EqualsAndHashCode(TYPE)利用父類方法和相關(guān)屬性生成equals()和hashCode() | callSuper:在使用本類屬性前先使用父類方法計(jì)算doNotUseGetters:不使用getter方法exclude:計(jì)算時(shí)不使用這里羅列的屬性of:計(jì)算時(shí)使用這里羅列的屬性onParam:同@Setter.onParam |
| @ToString(TYPE)利用父類方法和相關(guān)屬性生成 | callSuper:同@EqualsAndHashCode.callSuperdoNotUseGetters:同@EqualsAndHashCode.doNotUseGettersexclude:同@EqualsAndHashCode.excludeof:同@EqualsAndHashCode.ofincludeFieldNames:是否打印屬性名 |
1.7 日志
| 注解(位置) | 日志類類型 |
|---|---|
| @CommonsLog | org.apache.commons.logging.Log |
| @Log | java.util.logging.Logger |
| @JBossLog | org.jboss.logging.Logger |
| @Log4j | org.apache.log4j.Logger |
| @Log4j2 | org.apache.logging.log4j.Logger |
| @Slf4j | org.slf4j.Logger |
| @Slf4j2 | org.slf4j.ext.XLogger |
關(guān)于日志上的注解,重點(diǎn)應(yīng)該放在日志類型的選擇上。一般情況下優(yōu)先使用@Slf4j或@Slf4j2
1.8 雜項(xiàng)
| 注解(位置) | 日志類類型 |
|---|---|
| @NonNull(FIELD,METHOD,PARAMETER,LOCAL_VARIABLE)自動(dòng)生成引用空檢查代碼,為空時(shí)拋出空指針異常 | |
| @SneakThrows(METHOD,CONSTRUCTOR)自動(dòng)生成代碼,拋出受檢異常 | value:需要向上拋出的異常類型 |
| @Synchronized(METHOD)被標(biāo)注的方法使用生成的鎖對(duì)象(lock和Lock)而非默認(rèn)的(this和SlefType) | value:使用指定的屬性作為鎖對(duì)象 |
| @Value(TYPE)便捷地轉(zhuǎn)化可變類到不可變 | staticConstructor:同@RequiredArgsConstructor.staticName |
| @Cleanup(LOCAL_VARIABLE)生成自動(dòng)關(guān)閉資源的代碼 | value:使用指定的方法關(guān)閉資源,默認(rèn)使用close() |
- val 便捷地聲明final局部變量的類型(主要用于含有類型推斷的情況)
- var val的非final情況
除了上述提到的注解和類,在 lombok.experimental 中還包含一些處于實(shí)驗(yàn)階段中的注解(例如自動(dòng)生成代理方法的@Delegate等)和類,這里不再描述。
2. 使用Lombok
要在項(xiàng)目中使用Lombok,首先要在項(xiàng)目中引入lombok的依賴(使用Maven引入),重新編譯源代碼
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>
可根據(jù)項(xiàng)目自行選擇jar包版本:下載地址
IDEA中使用Lombok的注意事項(xiàng):
- 項(xiàng)目中要使用Lombok不僅IDEA要支持(否則一堆錯(cuò)誤),項(xiàng)目中也要引入jar包
- 如果配置lombok.config文件,修改文件的屬性值后,并不會(huì)自動(dòng)重新編譯class文件,IDEA編輯器也不會(huì)自動(dòng)更新,所有每次修改配置文件后最后關(guān)閉java文件窗口重新打開(kāi),并且clean下項(xiàng)目
2.1 常用注解
| 注解/關(guān)鍵字 | 可使用位置 | 說(shuō)明 |
|---|---|---|
| val | 局部變量 | 簡(jiǎn)化局部變量聲明的類型 |
| @NonNull | 字段、方法、入?yún)?、本地變?/td> | 生成檢查NullPointException代碼 |
| @Cleanup | 可關(guān)閉資源的本地變量對(duì)象,且銷毀方法沒(méi)有參數(shù) | 簡(jiǎn)化資源清理回收的代碼,消除try-catch-finally代碼塊 |
| @Getter / @Setter | 字段、枚舉常量、接口、類、枚舉、注解 | 簡(jiǎn)化getter、setter代碼 |
| @ToString | 接口、類、枚舉、注解 | 自動(dòng)生成toString方法(可以添加排除和依賴) |
| @EqualsAndHashCode | 接口、類、枚舉、注解 | 自動(dòng)生成equals方法和hashCode方法 |
| @NoArgsConstructor | 接口、類、枚舉、注解 | 生成無(wú)參構(gòu)造函數(shù) |
| @RequiredArgsConstructo | 接口、類、枚舉、注解 | 生成所有標(biāo)識(shí)為@NonNull的成員屬性的構(gòu)造函數(shù) |
| @AllArgsConstructor | 接口、類、枚舉、注解 | 生成包含所有成員屬性的構(gòu)造函數(shù) |
| @Data | 接口、類、枚舉、注解 | 是@ToString、@EqualsAndHashCode、@Getter、@Setter和@RequiredArgsConstructor的組合效果 |
| @Value | 接口、類、枚舉、注解 | 類似于@Data,區(qū)別在于字段會(huì)轉(zhuǎn)換為final類型,且沒(méi)有setter方法 |
| @NonFinal | 字段、方法、方法參數(shù)、本地變量、注解、接口、類、枚舉 | 用來(lái)取消因使用@FieldDefaults和@Value而加上的final修飾符 |
| @SneakyThrows | 方法、構(gòu)造函數(shù) | 粗粒度的try-catch,等同于try-catch 捕獲異常 |
| @Synchronized | 方法 | 作用等同于synchronized關(guān)鍵字,可自定義鎖對(duì)象 |
| @Log4j / @Slf4j / @Log | 接口、類、枚舉、注解 | 簡(jiǎn)化定義日志記錄器對(duì)象的代碼,根據(jù)日志框架的不同選擇不同的Log注解 |
| @Tolerate | 方法、注解 | 解決某些情況下使用Lombok注解生成的構(gòu)造器或方法與開(kāi)發(fā)者自己寫構(gòu)造器或方法因?yàn)闆_突而被跳過(guò)的情況 |
| @Builder | 類 | 會(huì)按builder模式生成一個(gè)內(nèi)部類 |
2.1.1 val / var
val用來(lái)簡(jiǎn)化局部變量聲明的類型,與Java10中的var關(guān)鍵字類似,都是從初始化表達(dá)式中推斷出變量的聲明類型,起到本地類型推斷的作用。需要注意的是val修飾的變量都會(huì)變成final類型,其引用不可更改。
val example = new ArrayList<String>();
example.add("hello");
example.add("lombok");
val element = example.get(0);
等價(jià)于:
final ArrayList<String> example = new ArrayList<String>();
example.add("hello");
example.add("lombok");
final String element = example.get(0);
注意:
- 1.只能在本地變量聲明的時(shí)候使用,不可在類的字段上使用
- 2.val修飾的變量本身是final類型的,不能被修改
var與val關(guān)鍵字類似,同樣起到本地類型推斷的作用,區(qū)別在于var修飾的變量不會(huì)轉(zhuǎn)變?yōu)閒inal類型,而val修飾的變量都會(huì)變成final類型
2.1.2 @NonNull
常用于加在方法和構(gòu)造函數(shù)的入?yún)⑸?,它?huì)幫助我們生成檢查NullPointerException的代碼
public NonNullExample(@NonNull Person person) {
this.name = person.getName();
}
等價(jià)于:
public NonNullExample(@NonNull Person person) {
if(person == null) {
throw new NullPointException("person");
}
this.name = person.getName();
}
2.1.3 @Cleanup
用來(lái)簡(jiǎn)化資源清理回收的代碼,確保指定的資源在退出當(dāng)前代碼執(zhí)行范圍前進(jìn)行自動(dòng)清理,消除常見(jiàn)的try-catch-finally代碼樣板,作用等同于try-with-resource,不過(guò)需要注意@Cleanup只能指定沒(méi)有參數(shù)的資源銷毀方法,如果銷毀方法有入?yún)t不能使用@Cleanup注解
public static void tradition() {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream("test.txt");
out = new FileOutputStream("output.txt");
byte[] buffer = new byte[1024];
int begin = 0;
while (true) {
int len = in.read(buffer);
if (len == -1)
break;
out.write(buffer, begin, len);
begin += len;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void tryWithResource() {
try (InputStream in = new FileInputStream("test.txt");
OutputStream out = new FileOutputStream("output.txt")) {
byte[] buffer = new byte[1024];
int begin = 0;
while (true) {
int len = in.read(buffer);
if (len == -1)
break;
out.write(buffer, begin, len);
begin += len;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void cleanUp() {
try {
@Cleanup InputStream in = new FileInputStream("test.txt");
@Cleanup OutputStream out = new FileOutputStream("output.txt");
byte[] buffer = new byte[1024];
int begin = 0;
while (true) {
int len = in.read(buffer);
if (len == -1)
break;
out.write(buffer, begin, len);
begin += len;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
2.1.4 @Getter / @Setter
分別用來(lái)簡(jiǎn)化getter和setter樣板代碼,默認(rèn)生成的getter、setter方法修飾符為public,如果需要指定方法的訪問(wèn)范圍,可以設(shè)置AccessLevel屬性,如:
@Getter @Setter(AccessLevel.PROTECTED) private String password;
另外,@Getter注解還有一個(gè)lazy=true的屬性,設(shè)置了該屬性會(huì)使我們調(diào)用getter方法時(shí)才真正去計(jì)算獲取到的值,并且將第一次計(jì)算后的結(jié)果緩存下來(lái),之后的調(diào)用直接返回該緩存值
@Getter(lazy = true)
private final double[] cached = expensive();
private double[] expensive() {
long begin = System.currentTimeMillis();
double[] result = new double[5];
for (int i = 0; i < result.length; i++) {
result[i] = Math.asin(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println((System.currentTimeMillis() - begin) / 1000);
return result;
}
public static void main(String[] args) {
GetterLazyExample example = new GetterLazyExample();
System.out.println(example.getCached());
System.out.println(example.getCached());
}
等價(jià)于:
private final AtomicReference<Object> cached = new AtomicReference<>();
public double[] getCached() {
Object value = this.cached.get();
if (value == null) {
synchronized (this.cached) {
value = this.cached.get();
if (value == null) {
final double[] actualValue = expensive();
value = actualValue == null ? this.cached : actualValue;
this.cached.set(value);
}
}
}
return (double[]) (value == this.cached ? null : value);
}
private double[] expensive() {
long begin = System.currentTimeMillis();
double[] result = new double[5];
for (int i = 0; i < result.length; i++) {
result[i] = Math.asin(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println((System.currentTimeMillis() - begin) / 1000);
return result;
}
public static void main(String[] args) {
GetterLazyExample_Src example = new GetterLazyExample_Src();
System.out.println(example.getCached());
System.out.println(example.getCached());
}
2.1.5 @ToString
用來(lái)自動(dòng)生成toString方法,默認(rèn)的toString方法會(huì)打印出類名和字段屬性和值,如果需要排除指定字段可以用exclude='字段名’的方式進(jìn)行排除;如果要嵌套調(diào)用父類的toString方法,則加上callSuper=true,includeFieldNames=true等屬性
// @ToString // 默認(rèn)打印類名、每個(gè)字段名=值,用逗號(hào)分隔
// @ToString(exclude="password") //exclude屬性指定排除哪些字段
@ToString(callSuper = true,includeFieldNames=true)
public class ToStringExample extends Parent {
@Getter
@Setter
private String name;
@Getter
@Setter
private String password;
@Getter
@Setter
private int age;
public static void main(String[] args) {
System.out.println(new ToStringExample());
}
}
@ToString
class Parent {
@Getter
@Setter
private String address;
@Getter
@Setter
private String city;
}
2.1.6 @EqualsAndHashCode
用來(lái)從字段中自動(dòng)生成equals和hashCode方法,默認(rèn)情況下使用的是所有非靜態(tài)字段,也可以使用exclude屬性排除指定的字段
@EqualsAndHashCode(exclude= {"name"})
public class EqualsAndHashCodeExample {
@Getter
@Setter
private String name;
@Getter
@Setter
private int age;
@Getter
@Setter
private double weight;
public static void main(String[] args) {
EqualsAndHashCodeExample example1 = new EqualsAndHashCodeExample();
example1.setName("小明");
example1.setAge(10);
EqualsAndHashCodeExample example2 = new EqualsAndHashCodeExample();
example2.setName("小紅");
example2.setAge(10);
System.out.println(example1.hashCode());
System.out.println(example2.hashCode());
System.out.println(example1.equals(example2));
}
}
2.1.6 @NoArgsConstructor
用來(lái)生成無(wú)參構(gòu)造函數(shù),如果類含有final字段,會(huì)出現(xiàn)編譯錯(cuò)誤,通過(guò)指定屬性force為true,為final字段進(jìn)行初始化
@NoArgsConstructor
public class NoArgsConstructorExample {
@Getter
@Setter
private String name;
}
等價(jià)于:
public class NoArgsConstructorExample {
private String name;
public NoArgsConstructorExample() {
//public無(wú)參構(gòu)造器
}
//省略getter、setter方法
......
}
2.1.7 @RequiredArgsConstructor
用來(lái)生成包含所有修飾為@NonNull的成員屬性的構(gòu)造函數(shù)
@RequiredArgsConstructor
public class RequiredArgsConstructorExample {
@Getter
@Setter
@NonNull
private String name;
@Getter
@Setter
private String password;
@Getter
@Setter
@NonNull
private Character sex;
}
等價(jià)于:
public class RequiredArgsConstructorExample {
private String name;
private String password;
private Character sex;
private RequiredArgsConstructorExample(String name, Character sex) {
if(name == null) {
throw new NullPointerException("name");
}
if(sex == null) {
throw new NullPointerException("sex");
}
this.name = name;
this.sex = sex;
}
//省略getter、setter方法
......
}
2.1.8 @AllArgsConstructor
@AllArgsConstructor
public class AllArgsContructorExample {
@Getter
@Setter
private String name;
@Getter
@Setter
private Integer age;
@Getter
@Setter
private String address;
}
等價(jià)于:
public class AllArgsContructorExample {
private String name;
private Integer age;
private String address;
public AllArgsContructorExample(String name, Integer age, String address) {
this.name = name,
this.age = age;
this.address = address;
}
//省略getter、setter方法
......
}
2.1.9 @Data
是一個(gè)簡(jiǎn)單粗暴的組合注解,使用@Data注解相當(dāng)于同時(shí)使用了@ToString、@EqualsAndHashCode、@Getter、@Setter和@RequiredArgsConstructor這幾個(gè)注解
@Data
public class DataExample {
private String name;
private int age;
private String password;
}
2.1.10 @Value
跟@Data類似,區(qū)別在于如果變量不加@NonFinal修飾,@Value會(huì)將字段變成final類型,同時(shí)也沒(méi)有setter方法
2.1.11 @NonFinal
修飾字段,用來(lái)取消因使用@FieldDefaults和@Value而加上的final修飾符
@Value
public class NonFinalExample {
private String id; //final
private String name; //final
@NonFinal
private String password; //非final
}
2.1.12 @Builder
簡(jiǎn)化了普通的建造者模式API,可以用在類、構(gòu)造器、方法上,如果字段屬于集合類型,加上@Singular,會(huì)生成兩個(gè)向集合中添加單一元素和所有元素的方法,以及一個(gè)清除集合的方法
@Builder
public class Example {
private int foo;
private final String bar;
}
等價(jià)于:
public class Example<T> {
private T foo;
private final String bar;
private Example(T foo, String bar) {
this.foo = foo;
this.bar = bar;
}
public static <T> ExampleBuilder<T> builder() {
return new ExampleBuilder<T>();
}
public static class ExampleBuilder<T> {
private T foo;
private String bar;
private ExampleBuilder() {}
public ExampleBuilder foo(T foo) {
this.foo = foo;
return this;
}
public ExampleBuilder bar(String bar) {
this.bar = bar;
return this;
}
@java.lang.Override
public String toString() {
return "ExampleBuilder(foo = " + foo + ", bar = " + bar + ")";
}
public Example build() {
return new Example(foo, bar);
}
}
}
2.1.13 @SneakyThrows
注解用在方法和構(gòu)造函數(shù)上,它會(huì)將方法中的所有代碼用try-catch語(yǔ)句包裹起來(lái),當(dāng)捕獲到異常后通過(guò)Lombok.sneakyThrow(e)將原始異常拋出,不過(guò)需要注意的是調(diào)用該方法的Client端并不知道會(huì)拋出哪種異常,即使這是一個(gè)CheckException
public class SneakyThrowsExample {
@SneakyThrows(UnsupportedEncodingException.class)
public static String utf8ToString(byte[] bytes) {
return new String(bytes, "UTF-8");
}
public static void main(String[] args) {
String str = SneakyThrowsExample.utf8ToString("hello lomboks".getBytes());
System.out.println(str);
}
}
2.1.14 @Synchronized
注解用在方法上,作用等同于synchronized關(guān)鍵字,區(qū)別在于鎖對(duì)象不同,對(duì)于synchronized關(guān)鍵字,修飾類方法時(shí)鎖對(duì)象是class對(duì)象,修飾成員方法時(shí)鎖對(duì)象是this對(duì)象,而使用@synchronized注解時(shí)鎖對(duì)象分別是私有靜態(tài)變量LOCK和私有final對(duì)象lock,也可以自己指定鎖對(duì)象
public class SynchronizedExample {
private final Object readLock = new Object();
@Synchronized("readLock")
@SneakyThrows
public void read() {
System.out.println(Thread.currentThread().getName() + " read");
Thread.sleep(3000);
}
public static void main(String[] args) {
SynchronizedExample example = new SynchronizedExample();
new Thread(()->example.read()).start();
new Thread(()->example.read()).start();
}
}
2.1.15 Log注解:@CommonsLog、@Log、@Log4j、@Log4j2、@Slf4j、@XSl4j、@JBossLog
Log注解可以省去從日志工廠生成日志記錄器對(duì)象的代碼,可以使用topic指定生成log對(duì)象時(shí)的類名,根據(jù)項(xiàng)目中使用的日志框架不同,有不同的注解可以選擇
@CommonsLog(topic="LogExample") //等價(jià)于 org.apache.commons.logging.LogFactory.getLog(LogExample.class); @Log(topic="LogExample") //等價(jià)于 java.util.loggin.Logger.getLogger(LogExample.class); @Log4j(topic="LogExample") //等價(jià)于 org.apache.log4j.Logger.getLogger(LogExample.class); @Log4j2(topic="LogExample") //等價(jià)于 org.apache.loggin.log4j.LogManager.getLoggerr(LogExample.class); @Slf4j(topic="LogExample") //等價(jià)于 org.slf4j.LoggerFactory.getLogger(LogExample.class); @XSLf4j(topic="LogExample") //等價(jià)于 org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class); @JBossLog(topic="LogExample") //等價(jià)于 org.jboss.logging.Logger.getLogger(LogExample.class);
2.1.16 @Tolerate
該注解用來(lái)解決某些情況下使用Lombok注解生成的構(gòu)造器或方法與開(kāi)發(fā)者自己寫構(gòu)造器或方法因?yàn)闆_突而被跳過(guò)的情況,將@Tolerate修飾在構(gòu)造器/方法上,會(huì)被lombok視為該構(gòu)造器/方法不存在,典型的如當(dāng)@Data和@Builder同時(shí)使用時(shí)Lombok生成構(gòu)造器只有一個(gè)包含所有成員屬性的構(gòu)造函數(shù),如果再自定義一個(gè)無(wú)參構(gòu)造函數(shù)將會(huì)沖突,此時(shí)可以使用@Tolerate解決
@Data
@Builder
public class TolerateExample {
private String name;
private String age;
@Tolerate
public TolerateExample() {
}
}
2.1.17 @UtilityClass
創(chuàng)建工具類的注釋,當(dāng)在類上加上該注解,該類會(huì)被修飾為final類型,如果該類聲明了構(gòu)造函數(shù)編譯器將會(huì)提示錯(cuò)誤,否則會(huì)自動(dòng)生成一個(gè)私有的構(gòu)造函數(shù),內(nèi)部拋出一個(gè)UnsupportedOperationException異常。并且所有的方法、內(nèi)部類和屬性都會(huì)被修飾為static
@UtilityClass
public class UtilityClassExample {
private DateFormat df = new SimpleDateFormat("YYYY-MM-DD");
public String formateToDay(Date date) {
return df.format(date);
}
}
等價(jià)于:
public class UtilityClassExample {
private static DateFormat df = new SimpleDateFormat("YYYY-MM-DD");
public static String formateToDay(Date date) {
return df.format(date);
}
private UtilityClassExample() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}
除了以上常用的基本功能外,Lombok還有部分實(shí)驗(yàn)性質(zhì)的特性沒(méi)有正式推薦使用,有些可能違背了對(duì)Java的常規(guī)認(rèn)知或者只支持部分開(kāi)發(fā)環(huán)境,所以不推薦使用
2.2 擴(kuò)展
2.2.1 lombok.config增加
lombok.equalsAndHashCode.doNotUseGetters = [true | false] (default:false)
如果設(shè)置為 true,lombok將直接訪問(wèn)字段,而不是在生成equals和hashcode方法時(shí)使用getter(如果可用),可以在該注解上配置屬性 donotusegetter 來(lái)標(biāo)示不使用getter的字段,這樣可以覆蓋默認(rèn)配置
lombok.equalsAndHashCode.callSuper = [call | skip | warn] (default:warn)
如果設(shè)置為 call,lombok將生成對(duì)hashCode的超類實(shí)現(xiàn)的調(diào)用
如果設(shè)置為 skip,則不會(huì)生成這樣的調(diào)用,默認(rèn)行為 warn 類似于 skip,并帶有附加警告。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
淺談Springboot下引入mybatis遇到的坑點(diǎn)
這篇文章主要介紹了Springboot下引入mybatis遇到的坑點(diǎn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
idea中一鍵自動(dòng)生成序列化serialVersionUID方式
這篇文章主要介紹了idea中一鍵自動(dòng)生成序列化serialVersionUID方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
Spring Boot項(xiàng)目添加外部Jar包以及配置多數(shù)據(jù)源的完整步驟
這篇文章主要給大家介紹了關(guān)于Spring Boot項(xiàng)目添加外部Jar包以及配置多數(shù)據(jù)源的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
使用idea開(kāi)發(fā)javaWeb應(yīng)用程序的思路(實(shí)現(xiàn)用戶的增刪改查)
這篇文章主要介紹了使用idea開(kāi)發(fā)javaWeb應(yīng)用程序的思路(實(shí)現(xiàn)用戶的增刪改查),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
SpringBoot多表聯(lián)查(測(cè)試可用)
這篇文章主要介紹了SpringBoot多表聯(lián)查(測(cè)試可用)的相關(guān)資料,需要的朋友可以參考下2017-09-09
Java打印出所有的水仙花數(shù)的實(shí)現(xiàn)代碼
這篇文章主要介紹了Java打印出所有的水仙花數(shù)的實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-02-02

