引言
開發中經常要創建一些實體類並要添加getter/setter方法、構造方法、toString方法等重複性工作,雖然IDEA有快捷鍵ALT+INSERT
快速實現,但我們想通過某種方式可以自動生成。這個時候就需要用到本篇的主角——Lombok。
簡介
Lombok是一款Java開發插件,可以通過它定義的註解來精簡代碼,主要針對簡單的Java模型對象(Plain Ordinary Java Object,即POJO)。特別是當POJO類的屬性增減時,這個時候如果使用註解,則不需要額外的操作,否則的話還得重新構建。而且Lombok針對這些內容的處理是在編譯期,而不是通過反射機制。
安裝
本篇是基於IDEA介紹。在IDEA中打開Settings—>Plugins,搜索Lombok,如下圖所示,點擊安裝,然後重啓IDEA。
插件安裝完成後在使用時需要在pom.xml中配置:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
使用說明
1. 作用在類上
1.1. @Data
@Data最常用的註解之一。作用在類上,提供該類所有屬性的get/set方法,還提供了equals、canEqual、hashCode、toString方法。並且默認是無參構造方法。
程序清單1:@Data註解
/**
* @author Carson Chu, [email protected]
* @date 2020/2/3 20:00
* @description
*/
@Data
public class UserInfoModel {
private String username;
private String password;
private Integer age;
public static void main(String[] args) {
UserInfoModel userInfoModel = new UserInfoModel();
userInfoModel.setUsername("Carson");
/* carson==>UserInfoModel(username=Carson, password=null, age=null) */
System.out.println(userInfoModel.getUsername() + "==>" + userInfoModel.toString());
}
}
1.2. @Value
作用於類上,會生成含所有參數的構造方法、get方法、equals、hashCode、toString方法。與@Data相比,多了全參構造方法,少了默認構造方法、set方法和canEqual方法。
需要注意的是:該註解會將字段添加上final修飾,個人感覺沒有太大必要,開發中儘量少使用。
程序清單2:@Value註解
/**
* @author Carson Chu, [email protected]
* @date 2020/2/3 20:00
* @description
*/
@Value
public class UserInfoModel {
private String username;
private String password;
private Integer age;
public static void main(String[] args) {
UserInfoModel userInfoModel = new UserInfoModel("Carson","2020",18);
/* Carson==>UserInfoModel(username=Carson, password=2020, age=18) */
System.out.println(userInfoModel.getUsername() + "==>" + userInfoModel.toString());
}
}
1.3. @Setter和@Getter
@Setter和@Getter用法相同,都可以作用在類上和變量上,當作用在類上,就是對類中所有屬性生成set或者get方法,當作用在變量上,則是對特定的變量生成set或者get方法。
程序清單3:@Setter和@Getter註解
@Setter
public class UserInfoModel {
private String username;
private String password;
@Getter
private Integer age;
}
1.4. @Log4j
作用於類上,爲該類提供一個參數名爲log的Log4j的日誌對象。
程序清單4:@Log4j註解
@Log4j
public class UserInfoModel {
public static void main(String[] args) {
log.info("@Log4j");
}
}
1.5. @AllArgsConstructor和@NoArgsConstructor
兩個註解都作用於類上,@AllArgsConstructor爲該類提供一個包含所有參數的構造方法。@NoArgsConstructor提供一個無參的構造方法,它可以和@AllArgsConstructor同時使用,此時會生成兩個構造方法:無參構造方法和全參構造方法。
程序清單5:@AllArgsConstructor和@NoArgsConstructor註解
@AllArgsConstructor
@NoArgsConstructor
public class UserInfoModel {
private String username;
private String password;
public static void main(String[] args) {
UserInfoModel userInfoModel=new UserInfoModel();
UserInfoModel userInfoModel1=new UserInfoModel("Carson","2020");
}
}
1.6. @RequiredArgsConstructor
作用於類上,由類中所有帶有@NonNull註解(接下來會說明)或者帶有final修飾的成員變量作爲參數生成構造方法。
程序清單6:@RequiredArgsConstructor註解
@RequiredArgsConstructor
public class UserInfoModel {
private final String username;
private String password;
@NonNull
private Integer age;
public static void main(String[] args) {
UserInfoModel userInfoModel = new UserInfoModel("Carson", 18);
}
}
1.7. @Builder
作用於類上,支持Builder的流式操作。
1.8. @ToString
作用於類上,生成包含所有參數的toString方法。
2. 作用在變量上
2.1 @NonNull
作用於變量上,提供關於此參數的非空檢查,如果參數爲空,則拋出空指針異常。如下圖所示,我們已經知道@Data會默認生成無參構造方法,但是當類中有參數被@NonNull修飾之後,無參構造方法將會失效,取而代之的是由所有@NonNull註解的變量組成的有參構造方法。
3. 作用在方法上
3.1 @Synchronized
作用於類方法或實例方法上,效果與synchronized相同。區別如下表所示:
加鎖方式 | 作用域 | 加鎖對象 |
---|---|---|
synchronized | 類方法 | 類的Class對象 |
synchronized | 實例方法 | this對象 |
@Synchronized | 類方法 | private static final對象 |
@Synchronized | 實例方法 | private final對象 |
當註解@Synchronized作用在非靜態方法時,需要在註解中指向一個自定義的private final鎖對象。
程序清單7:@Synchronized註解
public class UserInfoModel {
private final Object LOCK = new Object();
private static Integer staticCounter;
@Synchronized
public static int incr() {
return ++staticCounter;
}
@Synchronized("LOCK")
public int decr() {
return --staticCounter;
}
}
該類編譯之後的class文件爲:
public class UserInfoModel {
private static final Object $LOCK = new Object[0];
private final Object LOCK = new Object();
private static Integer staticCounter;
public UserInfoModel() {
}
public static int incr() {
synchronized($LOCK) {
return staticCounter = staticCounter + 1;
}
}
public int decr() {
synchronized(this.LOCK) {
return staticCounter = staticCounter - 1;
}
}
}
可以看到,程序爲@Synchronized註解作用的靜態方法自動創建了一個private static final類型的鎖對象private static final Object $LOCK = new Object[0];
。
3.1 @SneakyThrows
作用於方法上,相當於把方法內的代碼添加了一個try-catch處理。
小結
在本篇末對Lombok做個小結,說一下個人的看法,此神器雖然好用,但是在代碼的可讀性方面卻是不如手動生成的get/set、toString方法。開發工具雖然帶來了極大的便利,但軟件開發人員還是不應該過於依賴工具。該需要親自動手去實現的還是踏實一點,千里之行,始於足下。