說明:本文是博學谷課程整理的筆記,課程地址:https://xuexi.boxuegu.com/video.html?courseId=1586
lombok官網:https://projectlombok.org/
一、Lombok簡介
1. Lombok是什麼
Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java.
Never write another getter or equals method again, with one annotation your class has a fully featured builder, Automate your logging variables, and much more.
簡單說:
Lombok項目是一個Java實用工具庫,可以用來幫助開發人員消除Java中的冗長代碼,尤其是對於簡單的Java對象(POJO),它通過註解來實現這一目的。
2. Lombok原理
JSR 269:插件化註解處理API(Pluggable Annotation Processing API)——編譯期(SOURCE)註解,不同於運行期(RUNTIME)註解
官網:https://www.jcp.org/en/jsr/detail?id=269
JDK6提供的特性,在Javac編譯期利用註解搞事情!
3. Lombok安裝
3.1 javac
- 拷貝jar到類路徑
javac -cp lombok.jar ...
3.2 Maven
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
3.3 Intellij IDEA
官網:https://projectlombok.org/setup/intellij
Add the Lombok IntelliJ plugin to add lombok support for IntelliJ:
- Go to
File > Settings > Plugins
- Click on
Browse repositories...
- Search for
Lombok Plugin
- Click on
Install plugin
- Restart IntelliJ IDEA
二、Lombok常用註解
1. @Getter/@Setter
package top.onefine.lombok;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
// 給所有類中的成員變量生成get/set方法
// 不對static類型產生效果
// 對final類型只會產生get方法,不會產生set方法
@Setter
@Getter
public class User {
static String s = "";
final int id2 = 10;
// 只給id字段添加get/set方法
// @Getter(AccessLevel.PROTECTED) // 默認public
// @Setter // 默認public
private Integer id;
private String userName;
private String password;
private String phone;
@Getter(AccessLevel.NONE) // 不會生成對應的get方法,@Setter同理
private String email;
}
2. @ToString
package top.onefine.lombok;
import lombok.ToString;
//@ToString // 不會打印static類型的
//@ToString(exclude = {"email", "phone"}) // 不打印成員變量email和phone
@ToString(of = {"id2", "userName"}) // 只打印id和成員變量userName
public class User {
static String s = ""; // 不會打印
final int id2 = 10;
private Integer id;
private String userName;
private String password;
private String phone;
private String email;
}
3. @EqualsAndHashCode
package top.onefine.lombok;
import lombok.EqualsAndHashCode;
//@EqualsAndHashCode // 自動生成equals、canEqual、hashCode方法
//@EqualsAndHashCode(exclude = {"phone", "password"}) // 判斷時不比較phone和password字段
@EqualsAndHashCode(of = {"id"}) // 只根據id判斷
public class User {
static String s = "";
final int id2 = 10;
private Integer id;
private String userName;
private String password;
private String phone;
private String email;
}
4. @NonNull
package top.onefine.lombok;
import lombok.NonNull;
public class User {
@NonNull private Integer id;
public void test(@NonNull String str) { // 對實參str進行判斷,不允許其爲空
System.out.println(str);
}
public static void main(String[] args) {
new User().test(null);
}
}
對class字節碼反編譯之後發現:
// ...
@NonNull
private Integer id;
// ...
public void test(@NonNull String str) {
if (str == null) {
throw new NullPointerException("str is marked non-null but is null");
} else {
System.out.println(str);
}
}
5. @NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor
package top.onefine.lombok;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
//@NoArgsConstructor // 添加無參構造函數
@RequiredArgsConstructor // 默認對標識NonNull註解或final關鍵字(不指定值的情況下;但是此時不能有無參的構造函數)的成員變量生成構造函數
public class User {
static String s = "";
final int id2; // = 10;
@NonNull private Integer id;
private String userName;
private String password;
private String phone;
private String email;
}
反編譯之後:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package top.onefine.lombok;
import lombok.NonNull;
public class User {
static String s = "";
final int id2;
@NonNull
private Integer id;
private String userName;
private String password;
private String phone;
private String email;
public User(int id2, @NonNull Integer id) {
if (id == null) {
throw new NullPointerException("id is marked non-null but is null");
} else {
this.id2 = id2;
this.id = id;
}
}
}
package top.onefine.lombok;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
//@NoArgsConstructor // 添加無參構造函數
//@RequiredArgsConstructor // 默認對標識NonNull註解或final關鍵字(不指定值的情況下;但是此時不能有無參的構造函數)的成員變量生成構造函數
@AllArgsConstructor // 生成所有字段的構造函數
public class User {
static String s = "";
final int id2; // = 10;
@NonNull private Integer id;
private String userName;
private String password;
private String phone;
private String email;
}
反編譯之後:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package top.onefine.lombok;
import lombok.NonNull;
public class User {
static String s = "";
final int id2;
@NonNull
private Integer id;
private String userName;
private String password;
private String phone;
private String email;
public User(int id2, @NonNull Integer id, String userName, String password, String phone, String email) {
if (id == null) {
throw new NullPointerException("id is marked non-null but is null");
} else {
this.id2 = id2;
this.id = id;
this.userName = userName;
this.password = password;
this.phone = phone;
this.email = email;
}
}
}
6. @Data
package top.onefine.lombok;
import lombok.Data;
import lombok.NonNull;
@Data
public class User {
static String s = "";
final int id2; // = 10;
@NonNull private Integer id;
private String userName;
private String password;
private String phone;
private String email;
}
直接上圖:
@Data集成了@Getter/@Setter、@ToString、@EqualsAndHashCode、@RequiredArgsConstructor四個註解。
7. @Builder
package top.onefine.lombok;
import lombok.Builder;
import lombok.NonNull;
@Builder
public class User {
static String s = "";
final int id2 = 10;
@NonNull private Integer id;
private String userName;
private String password;
private String phone;
private String email;
}
直接上圖:
反編譯結果:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package top.onefine.lombok;
import lombok.NonNull;
public class User {
static String s = "";
final int id2 = 10;
@NonNull
private Integer id;
private String userName;
private String password;
private String phone;
private String email;
User(@NonNull Integer id, String userName, String password, String phone, String email) {
if (id == null) {
throw new NullPointerException("id is marked non-null but is null");
} else {
this.id = id;
this.userName = userName;
this.password = password;
this.phone = phone;
this.email = email;
}
}
public static top.onefine.lombok.User.UserBuilder builder() {
return new top.onefine.lombok.User.UserBuilder();
}
}
用法:
package top.onefine.lombok;
import lombok.Builder;
import lombok.NonNull;
import lombok.ToString;
@Builder
@ToString
public class User {
static String s = "";
final int id2 = 10;
@NonNull private Integer id;
private String userName;
private String password;
private String phone;
private String email;
public static void main(String[] args) {
User user = User.builder().id(123).email("[email protected]").userName("one fine").build();// ...
System.out.println(user);
}
}
執行結果:
User(id2=10, id=123, userName=one fine, password=null, phone=null, [email protected])
8. @Log
package top.onefine.lombok;
import lombok.NonNull;
import lombok.extern.java.Log;
@Log
public class User {
static String s = "";
final int id2 = 10;
@NonNull private Integer id;
private String userName;
private String password;
private String phone;
private String email;
public static void main(String[] args) {
log.info("info msg...");
}
}
執行結果:
3月 09, 2020 11:29:31 下午 top.onefine.lombok.User main
信息: info msg...
反編譯之後:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package top.onefine.lombok;
import java.util.logging.Logger;
import lombok.NonNull;
public class User {
private static final Logger log = Logger.getLogger(User.class.getName());
static String s = "";
final int id2 = 10;
@NonNull
private Integer id;
private String userName;
private String password;
private String phone;
private String email;
public User() {
}
public static void main(String[] args) {
log.info("info msg...");
}
}
9. val
package top.onefine.lombok;
import java.util.HashMap;
import lombok.val;
public class User {
public static void main(String[] args) {
// HashMap<String, String> map = new HashMap<>();
val map = new HashMap<String, String>();
map.put("name", "one fine");
}
}
反編譯後:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package top.onefine.lombok;
import java.util.HashMap;
public class User {
public User() {
}
public static void main(String[] args) {
HashMap<String, String> map = new HashMap();
map.put("name", "one fine");
}
}
10. @Cleanup
package top.onefine.lombok;
import java.io.*;
import lombok.Cleanup;
public class User {
public static void main(String[] args) throws IOException {
@Cleanup InputStream in = new FileInputStream("path1"); // 不用手動關閉
@Cleanup OutputStream out = new FileOutputStream("path2"); // 不用手動關閉
byte[] b = new byte[100];
while (true) {
int r = in.read(b);
if (r == -1)
break;
out.write(b, 0, r);
}
}
}
字節碼反編譯之後:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package top.onefine.lombok;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collections;
public class User {
public User() {
}
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("path1");
try {
FileOutputStream out = new FileOutputStream("path2");
try {
byte[] b = new byte[100];
while(true) {
int r = in.read(b);
if (r == -1) {
return;
}
out.write(b, 0, r);
}
} finally {
if (Collections.singletonList(out).get(0) != null) {
out.close();
}
}
} finally {
if (Collections.singletonList(in).get(0) != null) {
in.close();
}
}
}
}