C#寫的多了用習慣了眾多的語法糖,再寫起來Java總會有一些非常不舒服的地方。比如用慣了C#的屬性在用起來Java的屬性,寫起來就會感覺不夠優雅。如:定義一個Person
類
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Describe { get; set; }
}
而同樣的代碼,java寫起來就...
public class Person {
private String name;
private Integer age;
private String escribe;
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getEscribe() {
return escribe;
}
public void setEscribe(String escribe) {
this.escribe = escribe;
}
}
為了能夠更優雅的編碼,我們可以使用Lombok
一、Lombok介紹
Lombok是一個Java庫,能自動插入編輯器並構建工具,簡化Java開發。通過添加注解的方式,不需要為類編寫getter或equals方法,同時可以自動化日志變量...官網鏈接
簡單來說,這玩意能以簡單注解的方式簡化Java代碼,以提高開發效率
二、 項目中引入Lombok
- 添加maven依賴
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
- 創建一個
Person
類,並為其加上@Data
注解
package spring.boot.lombok.model;
import lombok.Data;
@Data
public class Person_Lombok {
private String name;
private Integer age;
private String describe;
}
- 安裝idea插件
使用Lombok還需要插件的配合,打開idea的設置,點擊Plugins,點擊Browse repositories,在彈出的窗口中搜索lombok,然后安裝即可。
編譯時出錯,可能是沒有enable注解處理器。Annotation Processors > Enable annotation processing
。設置完成之后程序正常運行。
- 測試運行
package spring.boot.lombok;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import spring.boot.lombok.model.Person_Lombok;
@RunWith(SpringRunner.class)
@SpringBootTest
public class Person_LombokTests {
@Autowired
public Person_Lombok person;
@Test
public void Test() {
person.setName("王小二");
person.setAge(19);
person.setDescribe("豆蔻年華,正青春!");
Assert.assertTrue(person.getAge() == 19);
}
}
三、Lombok常用注解
@Setter
注解在類或字段,注解在類時為所有字段生成setter方法,注解在字段上時只為該字段生成setter方法。@Getter
使用方法同上,區別在於生成的是getter方法。@ToString
注解在類,添加toString方法。@EqualsAndHashCode
注解在類,生成hashCode和equals方法。@NoArgsConstructor
注解在類,生成無參的構造方法。@RequiredArgsConstructor
注解在類,為類中需要特殊處理的字段生成構造方法,比如final和被@NonNull注解的字段。@AllArgsConstructor
注解在類,生成包含類中所有字段的構造方法。@Data
注解在類,生成setter/getter、equals、canEqual、hashCode、toString方法,如為final屬性,則不會為該屬性生成setter方法。@Slf4j
注解在類,生成log變量,嚴格意義來說是常量。private static final Logger log = LoggerFactory.getLogger(UserController.class);@NonNull
給方法參數增加這個注解會自動在方法內對該參數進行是否為空的校驗,如果為空,則拋出NPE(NullPointerException)@Cleanup
自動管理資源,用在局部變量之前,在當前變量范圍內即將執行完畢退出之前會自動清理資源,自動生成try-finally這樣的代碼來關閉流@Synchronized
用在方法上,將方法聲明為同步的,並自動加鎖,而鎖對象是一個私有的屬性\(lock或\)LOCK,而java中的synchronized關鍵字鎖對象是this,鎖在this或者自己的類對象上存在副作用,就是你不能阻止非受控代碼去鎖this或者類對象,這可能會導致競爭條件或者其它線程錯誤@SneakyThrows
自動拋受檢異常,而無需顯式在方法上使用throws語句
四、Lombok原理解析
我們可以反編譯一下,idea為我們生成的.class文件,
可以看到雖然使用了lombok后我們沒有寫get,set等方法,但是是因為idea安裝了lombok的插件,在編譯的時候幫我們生成了這些方法。
在Lombok使用的過程中,只需要添加相應的注解,無需再為此寫任何代碼。核心之處就是對於注解的解析上。JDK5引入了注解的同時,也提供了兩種解析方式。
- 運行時解析
運行時能夠解析的注解,必須將@Retention
設置為RUNTIME
,這樣就可以通過反射拿到該注解。java.lang.reflect
反射包中提供了一個接口AnnotatedElement
,該接口定義了獲取注解信息的幾個方法,Class、Constructor、Field、Method、Package等都實現了該接口。
- 編譯時解析
編譯時解析有兩種機制,分別簡單描述下:
1)Annotation Processing Tool
apt自JDK5產生,JDK7已標記為過期,不推薦使用,JDK8中已徹底刪除,自JDK6開始,可以使用Pluggable Annotation Processing API來替換它,apt被替換主要有2點原因:
- api都在com.sun.mirror非標准包下
- 沒有集成到javac中,需要額外運行
2)Pluggable Annotation Processing API
JSR 269
自JDK6加入,作為apt的替代方案,它解決了apt的兩個問題,javac在執行的時候會調用實現了該API的程序,這樣我們就可以對編譯器做一些增強,javac執行的過程如下:
Lombok
本質上就是一個實現了JSR 269 API
的程序。在使用javac的過程中,它產生作用的具體流程如下:
javac
對源代碼進行分析,生成了一棵抽象語法樹(AST)- 運行過程中調用實現了
JSR 269 API
的Lombok
程序 - 此時
Lombok
就對第一步驟得到的AST進行處理,找到@Data注解所在類對應的語法樹AST,然后修改該語法樹AST,增加getter和setter方法定義的相應樹節點 javac
使用修改后的抽象語法樹AST生成字節碼文件,即給class增加新的節點(代碼塊)
五、Lombok優缺點
優點:
-
能通過注解的形式自動生成構造器、getter/setter、equals、hashcode、toString等方法,提高了一定的開發效率
-
讓代碼變得簡潔,不用過多的去關注相應的方法
-
屬性做修改時,也簡化了維護為這些屬性所生成的getter/setter方法等
缺點:
-
不支持多種參數構造器的重載
-
雖然省去了手動創建getter/setter方法的麻煩,但大大降低了源代碼的可讀性和完整性。