Lombok 工具简记与排坑

写了好久的 kotlin 了,在家回到 java 8 确实不习惯,甚至 lambda 都得想半天才能凑出来,lombok 注解也都只有个印象了,翻了一下官方文档,简单记录一下 lombok 的注解。
(不得不说版本越新越简便,可惜成都好多公司甚至都还在写 jsp,真是能用就行 = =

使用

val 与 var

用法和 kotlin 的一致,java 11 开始也支持 var 定义了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

import java.util.ArrayList;
import java.util.HashMap;
import lombok.val;
import lombok.var;

public class ValExample {
public String example() {
// 不可变量,自动匹配类型
// 等效于
//final ArrayList<String> example = new ArrayList<String>();
val example = new ArrayList<String>();
example.add("Hello, World!");
// 可变量,自动匹配类型
// 等效于
//String foo = example.get(0);
var foo = example.get(0);
//val 在重新赋值时会报错
example = new ArrayList<String>(); // 无法被编译
//var 可以重新赋值,但只能赋值之前定义好的类型
foo = "Hi"; // 编译正常通过
foo = 1; // 无法被编译
return foo.toLowerCase();
}
}

@Cleanup

省略了常用文件流中的 try{}cartch{}finnally{} 代码块,以下时官方案例。不过相应的工具类确实很多,尝鲜用吧

Lombok

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import lombok.Cleanup;
import java.io.*;

public class CleanupExample {
public static void main(String[] args) throws IOException {
@Cleanup InputStream in = new FileInputStream(args[0]);
@Cleanup OutputStream out = new FileOutputStream(args[1]);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
}
}

JAVA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.io.*;

public class CleanupExample {
public static void main(String[] args) throws IOException {
InputStream in = new FileInputStream(args[0]);
try {
OutputStream out = new FileOutputStream(args[1]);
try {
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
} finally {
if (out != null) {
out.close();
}
}
} finally {
if (in != null) {
in.close();
}
}
}
}

排坑

@Build 在和 @Data 共用时无法创建无参构造

这个时候需要手动引入或者使用注解 @NoArgsConstructor

@Accessors 中设置了 fluent 属性为 true 时,fastJson 将无法正常工作

原因是 fastJson 使用前缀匹配的方式截取 get()set() 方法,从而拿到属性名。

fluent 属性则会去除前缀,直接以类的成员变量名作为方法名,通过重写的方式实现 get()set() 方法。这会导致 fastJson 无法查找到对应的访问方法,从而无法对类序列化或反序列

这个问题是所有通过 getset 前缀匹配操作实体类都会出现的,建议不对其进行设置(默认为 false)。

同时,fastJson 针对 boolean 类型使用的前缀判断是 is ,而 @Data 注解对以 is 前缀的属性生成 get()set() 时也 不会创建 get 前缀 的方法名,此时 fastJson 虽然能对其序列化,但获取到的属性名实则是不带有 is 前缀的,从而导致数据有误。

这时候最好是更改属性

1
2
3
private boolean isHappy;
// 修改为
private boolean happyFlag;

或者手动创建对应的 get 前缀方法