Lombok Project 是一個很小的 Java Annotation Library,目的是消除 Java 中一直不斷發生的重複程式碼,以 Java Bean 為例,最常見的就是需要在撰寫 class member 後,還需要寫一堆重複的 getter/setter,雖然 IDE 可以協助產生這些程式碼,但遇到欄位名稱修改,或是增刪欄位時,還是會造成困擾。
Installation
參考 Lombok 網頁的 Install 部分,基本上針對 project,就參考 Build tools 的部分,以我們使用來說,是看 maven。
在 Maven POM 裡面加上這個 dependency library,就可以使用了。
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
另外,通常 project 會搭配某個 IDE 進行開發,我們在 Intellij IDEA 安裝 Lombok plugin。
- 在 Plugins 功能中,Browse repositories
- 然後搜尋 Lombok Plugin
- Install Plugin
- Restart IDEA
因為 Lombok 只會將程式碼產生在編譯後的 class 裡面,在 IDE 必須要搭配 Plugin,才能偵測到 Lombok Plugin,並在編譯前了解 Lombok 會產生的 method/code,安裝了 Plugin 才不會看到編譯 Error 的警告。
Features
@Getter @Setter
@Getter
@Setter
private boolean employed = true;
@Setter(AccessLevel.PROTECTED)
private String name;
就等於以下的 Java Code
private boolean employed = true;
private String name;
public boolean isEmployed() {
return employed;
}
public void setEmployed(final boolean employed) {
this.employed = employed;
}
protected void setName(final String name) {
this.name = name;
}
@NonNull
會在 setter 產生 null check,發生 null 時,會產生 NullPointerException。
@Getter
@Setter
@NonNull
private String lastname;
等同以下 java code
public void setLastname(String lastname) {
if (lastname == null) throw new java.lang.NullPointerException("lastname");
this.lastname = lastname;
}
public String getLastname() {
return lastname;
}
@ToString
@ToString(callSuper=true,exclude="employed")
public class TestBean {
private boolean employed = true;
private String name;
private String lastname;
}
等同以下 java code
public class TestBean {
private boolean employed = true;
private String name;
private String lastname;
@java.lang.Override
public java.lang.String toString() {
return "TestBean("super=" + super.toString() +
", name =" + name +
", lastname =" + lastname + ")";
}
}
@EqualsAndHashCode
產生 equals 與 hashCode
@EqualsAndHashCode(callSuper=true, exclude={"employed"})
public class TestBean extends Person {
private boolean employed = true;
private String name;
private String lastname;
}
等同以下 java code
public class TestBean extends Person {
private boolean employed = true;
private String name;
private String lastname;
@java.lang.Override
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (o == null) return false;
if (o.getClass() != this.getClass()) return false;
if (!super.equals(o)) return false;
final TestBean other = (TestBean)o;
if (this.name == null ? other.name != null : !this.name.equals(other.name)) return false;
if (this.lastname == null ? other.lastname != null : !this.lastname.equals(other.lastname)) return false;
return true;
}
@java.lang.Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = result * PRIME + super.hashCode();
result = result * PRIME + (this.name == null ? 0 : this.name.hashCode());
result = result * PRIME + (this.lastname == null ? 0 : this.lastname.hashCode());
return result;
}
}
@Data
這是 Lombok 最常用的 annotation,包含了 @ToString, @EqualsAndHashCode, @Getter, @Setter 的功能。
@Cleanup
可確保 resource 會被 released,但 Java 7 以後已經有了 auto resource management 的功能,所以可以不使用這個功能。
@Synchronized
會產生一個 locking field,也就是 $lock 物件,用來同步該 method
private DateFormat format = new SimpleDateFormat("MM-dd-YYYY");
@Synchronized
public String synchronizedFormat(Date date) {
return format.format(date);
}
等同以下 java code
private final java.lang.Object $lock = new java.lang.Object[0];
private DateFormat format = new SimpleDateFormat("MM-dd-YYYY");
public String synchronizedFormat(Date date) {
synchronized ($lock) {
return format.format(date);
}
}
@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor
@NoArgsConstructor 會產生沒有 parameters 的 constructor,但如果有 final field 時,則無法使用這個 annotation,會發生編譯錯誤。
但可以改用 @NoArgsConstructor(force = true)
,這會將所有 final fields 初始化為 0/false/null。
@RequiredArgsConstructor 會產生一個 constructor,針對每一個需要特殊處理的 fields,都會產生一個參數,例如 final field,以及標記為 @NonNull field。
@AllArgsConstructor 會產生一個 constructor,class 裡面每一個 field 都產生一個對應的 constructor 參數
javap
編譯後的 class 可利用 javap 工具反組譯,並瞭解 Lombok 產生的 class 裡面包含的內容。
$ javap TestBean.class
Compiled from "TestBean.java"
public class test.TestBean extends test.Person {
public test.TestBean();
public boolean equals(java.lang.Object);
protected boolean canEqual(java.lang.Object);
public int hashCode();
}
Summary
其他的 annotaion 可參考 features 網頁的說明,但明顯最常用的是 @Data,這個功能就能減輕不少工作。
沒有留言:
張貼留言