Lombok

作用:帮使用者提高编码效率,减少重复与冗余的代码

原理:ASM   动态修改 class 文件


配置

maven

依赖

1
2
3
4
5
 <dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.8</version>
</dependency>

编译

1
2
3
4
5
6
7
8
9
    <build>
<plugins>
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.16.6.1</version>
</plugin>
</plugins>
</build>

idea

  • 安装插件

常用注解:

java bean 相关

@Setter

  • 功能

生成 setter 方法

  • 源码
1
2
3
4
5
6
@Setter
public class LombokDemo {

private Integer id;
private String name;
}
  • 编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

package xyz.mrwood.study.lombok;

public class LombokDemo {
private Integer id;
private String name;

public LombokDemo() {
}

public void setId(Integer id) {
this.id = id;
}

public void setName(String name) {
this.name = name;
}
}

@Getter

  • 功能

生成 getter 方法

  • 源码
1
2
3
4
5
6
@Getter
public class LombokDemo {

private Integer id;
private String name;
}
  • 编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package xyz.mrwood.study.lombok;

public class LombokDemo {
private Integer id;
private String name;

public LombokDemo() {
}

public Integer getId() {
return this.id;
}

public String getName() {
return this.name;
}
}

@ToString

  • 功能

生成 toString 方法

  • 源码
1
2
3
4
5
6
@ToString
public class LombokDemo {

private Integer id;
private String name;
}
  • 编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
package xyz.mrwood.study.lombok;

public class LombokDemo {
private Integer id;
private String name;

public LombokDemo() {
}

public String toString() {
return "LombokDemo(id=" + this.id + ", name=" + this.name + ")";
}
}

@Getter(lazy = true)

  • 功能

懒加载属性

  • 注意:

这个与上面@Getter 不同,那个是修饰在类上的,也可以修饰在属性上。如果有 lazy=true 只能修饰在属性,并且还要是 private final 修饰,限制很大

  • 编码
1
2
3
4
5
public class LombokDemo {

@Getter(lazy = true) private final List<Integer> ids = Arrays.asList(1, 2, 3, 4);
private String name;
}
  • 编译后
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
27
28
29
30
package xyz.mrwood.study.lombok;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

public class LombokDemo {
private final AtomicReference<Object> ids = new AtomicReference();
private String name;

public LombokDemo() {
}

public List<Integer> getIds() {
Object value = this.ids.get();
if(value == null) {
AtomicReference var2 = this.ids;
synchronized(this.ids) {
value = this.ids.get();
if(value == null) {
List actualValue = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4)});
value = actualValue == null?this.ids:actualValue;
this.ids.set(value);
}
}
}

return (List)((List)(value == this.ids?null:value));
}
}

@EqualsAndHashCode

  • 功能

生成 equals 方法与 hashCode 方法

  • 源码
1
2
3
4
5
6
@EqualsAndHashCode
public class LombokDemo {

private Integer id;
private String name;
}
  • 编译后
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package xyz.mrwood.study.lombok;

public class LombokDemo {
private Integer id;
private String name;

public LombokDemo() {
}

public boolean equals(Object o) {
if(o == this) {
return true;
} else if(!(o instanceof LombokDemo)) {
return false;
} else {
LombokDemo other = (LombokDemo)o;
if(!other.canEqual(this)) {
return false;
} else {
Integer this$id = this.id;
Integer other$id = other.id;
if(this$id == null) {
if(other$id != null) {
return false;
}
} else if(!this$id.equals(other$id)) {
return false;
}

String this$name = this.name;
String other$name = other.name;
if(this$name == null) {
if(other$name != null) {
return false;
}
} else if(!this$name.equals(other$name)) {
return false;
}

return true;
}
}
}

protected boolean canEqual(Object other) {
return other instanceof LombokDemo;
}

public int hashCode() {
boolean PRIME = true;
byte result = 1;
Integer $id = this.id;
int result1 = result * 59 + ($id == null?43:$id.hashCode());
String $name = this.name;
result1 = result1 * 59 + ($name == null?43:$name.hashCode());
return result1;
}
}

@NoAragsConstructor

  • 功能

添加一个无参构造函数

  • 注意

这个注解在没有其它有参构造函数的情况下使用意义不大,因为在这种情况下 java 默认会添加一个无参构造函数

  • 源码
1
2
3
4
5
6
@NoArgsConstructor
public class LombokDemo {

private Integer id;
private String name;
}
  • 编译后
1
2
3
4
5
6
7
8
9
package xyz.mrwood.study.lombok;

public class LombokDemo {
private Integer id;
private String name;

public LombokDemo() {
}
}

@AllArgsConstructor

  • 功能

添加一个所有参数的构造函数

  • 源码
1
2
3
4
5
6
@AllArgsConstructor
public class LombokDemo {

private Integer id;
private String name;
}
  • 编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package xyz.mrwood.study.lombok;

import java.beans.ConstructorProperties;

public class LombokDemo {
private Integer id;
private String name;

@ConstructorProperties({"id", "name"})
public LombokDemo(Integer id, String name) {
this.id = id;
this.name = name;
}
}

@RequiredArgsConstructor

  • 功能

生成一个包含必填参数的构造函数

  • 注意

要与@NonNull 搭配使用,该注解修饰的属性就是必填参数

  • 源码
1
2
3
4
5
6
@RequiredArgsConstructor
public class LombokDemo {

@NonNull private Integer id;
private String name;
}
  • 编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package xyz.mrwood.study.lombok;

import java.beans.ConstructorProperties;
import lombok.NonNull;

public class LombokDemo {
@NonNull
private Integer id;
private String name;

@ConstructorProperties({"id"})
public LombokDemo(@NonNull Integer id) {
if(id == null) {
throw new NullPointerException("id");
} else {
this.id = id;
}
}
}

@Data

  • 功能

这是一个综合注解了,等于同时使用

@Getter, @Setter, @ToString, @EqualsAndHashCode,@RequiredArgsConstructor

  • 源码
1
2
3
4
5
6
@Data
public class LombokDemo {

@NonNull private Integer id;
private String name;
}
  • 编译后
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package xyz.mrwood.study.lombok;

public class LombokDemo {
private Integer id;
private String name;

public LombokDemo() {
}

public Integer getId() {
return this.id;
}

public String getName() {
return this.name;
}

public void setId(Integer id) {
this.id = id;
}

public void setName(String name) {
this.name = name;
}

public boolean equals(Object o) {
if(o == this) {
return true;
} else if(!(o instanceof LombokDemo)) {
return false;
} else {
LombokDemo other = (LombokDemo)o;
if(!other.canEqual(this)) {
return false;
} else {
Integer this$id = this.getId();
Integer other$id = other.getId();
if(this$id == null) {
if(other$id != null) {
return false;
}
} else if(!this$id.equals(other$id)) {
return false;
}

String this$name = this.getName();
String other$name = other.getName();
if(this$name == null) {
if(other$name != null) {
return false;
}
} else if(!this$name.equals(other$name)) {
return false;
}

return true;
}
}
}

protected boolean canEqual(Object other) {
return other instanceof LombokDemo;
}

public int hashCode() {
boolean PRIME = true;
byte result = 1;
Integer $id = this.getId();
int result1 = result * 59 + ($id == null?43:$id.hashCode());
String $name = this.getName();
result1 = result1 * 59 + ($name == null?43:$name.hashCode());
return result1;
}

public String toString() {
return "LombokDemo(id=" + this.getId() + ", name=" + this.getName() + ")";
}
}

@Value

  • 功能

不可变类的@Data, 他会默认给属性加上 final

  • 源码
1
2
3
4
5
6
@Value
public class LombokDemo {

private Integer id;
private String name;
}
  • 编译后
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package xyz.mrwood.study.lombok;

import java.beans.ConstructorProperties;

public final class LombokDemo {
private final Integer id;
private final String name;

@ConstructorProperties({"id", "name"})
public LombokDemo(Integer id, String name) {
this.id = id;
this.name = name;
}

public Integer getId() {
return this.id;
}

public String getName() {
return this.name;
}

public boolean equals(Object o) {
if(o == this) {
return true;
} else if(!(o instanceof LombokDemo)) {
return false;
} else {
LombokDemo other = (LombokDemo)o;
Integer this$id = this.getId();
Integer other$id = other.getId();
if(this$id == null) {
if(other$id != null) {
return false;
}
} else if(!this$id.equals(other$id)) {
return false;
}

String this$name = this.getName();
String other$name = other.getName();
if(this$name == null) {
if(other$name != null) {
return false;
}
} else if(!this$name.equals(other$name)) {
return false;
}

return true;
}
}

public int hashCode() {
boolean PRIME = true;
byte result = 1;
Integer $id = this.getId();
int result1 = result * 59 + ($id == null?43:$id.hashCode());
String $name = this.getName();
result1 = result1 * 59 + ($name == null?43:$name.hashCode());
return result1;
}

public String toString() {
return "LombokDemo(id=" + this.getId() + ", name=" + this.getName() + ")";
}
}

@Accessors

  • 功能

这个注解要搭配@Getter 与@Setter 使用,用来修改默认的 setter 与 getter 方法的形式

  • 注意

@Accessors 有三个参数可以使用

  1. chain   链式的形式
  1. fluent   流式的形式
  1. prefix   生成指定前缀的属性的 getter 与 setter 方法,并且生成的 getter 与 setter 方法时会去除前缀
  • 源码 chain = true
1
2
3
4
5
6
7
8
@Accessors(chain = true)
@Setter
@Getter
public class LombokDemo {

private Integer id;
private String name;
}
  • 编译后 chain = true
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
27
package xyz.mrwood.study.lombok;

public class LombokDemo {
private Integer id;
private String name;

public LombokDemo() {
}

public LombokDemo setId(Integer id) {
this.id = id;
return this;
}

public LombokDemo setName(String name) {
this.name = name;
return this;
}

public Integer getId() {
return this.id;
}

public String getName() {
return this.name;
}
}
  • 源码 fluent = true
1
2
3
4
5
6
7
8
@Accessors(fluent = true)
@Setter
@Getter
public class LombokDemo {

private Integer id;
private String name;
}
  • 编译后 fluent = true
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
27
package xyz.mrwood.study.lombok;

public class LombokDemo {
private Integer id;
private String name;

public LombokDemo() {
}

public LombokDemo id(Integer id) {
this.id = id;
return this;
}

public LombokDemo name(String name) {
this.name = name;
return this;
}

public Integer id() {
return this.id;
}

public String name() {
return this.name;
}
}
  • 源码 prefix = "xxx"
1
2
3
4
5
6
7
8
@Accessors(prefix = "xxx")
@Setter
@Getter
public class LombokDemo {

private Integer xxxId;
private String name;
}
  • 编译后 prefix = "xxx"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package xyz.mrwood.study.lombok;

public class LombokDemo {
private Integer xxxId;
private String name;

public LombokDemo() {
}

public void setId(Integer xxxId) {
this.xxxId = xxxId;
}

public Integer getId() {
return this.xxxId;
}
}

其它注解:

日志相关

@Log4j

  • 源码
1
2
3
4
5
6
@Log4j
public class LombokDemo {

private Integer xxxId;
private String name;
}
  • 编译后
1
2
3
4
5
6
7
8
9
10
11
12
package xyz.mrwood.study.lombok;

import org.apache.log4j.Logger;

public class LombokDemo {
private static final Logger log = Logger.getLogger(LombokDemo.class);
private Integer xxxId;
private String name;

public LombokDemo() {
}
}

@CommonsLog

  • 源码
1
2
3
4
5
6
@CommonsLog
public class LombokDemo {

private Integer xxxId;
private String name;
}
  • 编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
package xyz.mrwood.study.lombok;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class LombokDemo {
private static final Log log = LogFactory.getLog(LombokDemo.class);
private Integer xxxId;
private String name;

public LombokDemo() {
}
}

@Log

  • 源码
1
2
3
4
5
6
@Log
public class LombokDemo {

private Integer xxxId;
private String name;
}
  • 编译后
1
2
3
4
5
6
7
8
9
10
11
12
package xyz.mrwood.study.lombok;

import java.util.logging.Logger;

public class LombokDemo {
private static final Logger log = Logger.getLogger(LombokDemo.class.getName());
private Integer xxxId;
private String name;

public LombokDemo() {
}
}

@Log4j2

  • 源码
1
2
3
4
5
6
@Log4j2
public class LombokDemo {

private Integer xxxId;
private String name;
}
  • 编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
package xyz.mrwood.study.lombok;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class LombokDemo {
private static final Logger log = LogManager.getLogger(LombokDemo.class);
private Integer xxxId;
private String name;

public LombokDemo() {
}
}

@Slf4j

  • 源码
1
2
3
4
5
6
@Slf4j
public class LombokDemo {

private Integer xxxId;
private String name;
}
  • 编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
package xyz.mrwood.study.lombok;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LombokDemo {
private static final Logger log = LoggerFactory.getLogger(LombokDemo.class);
private Integer xxxId;
private String name;

public LombokDemo() {
}
}

设计模式相关

@Builder

  • 功能

通过建造者模块来生成 bean

  • 源码
1
2
3
4
5
6
@Builder
public class LombokDemo {

private Integer id;
private String name;
}
  • 编译后
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package xyz.mrwood.study.lombok;

public class LombokDemo {
private Integer id;
private String name;

LombokDemo(Integer id, String name) {
this.id = id;
this.name = name;
}

public static LombokDemo.LombokDemoBuilder builder() {
return new LombokDemo.LombokDemoBuilder();
}

public static class LombokDemoBuilder {
private Integer id;
private String name;

LombokDemoBuilder() {
}

public LombokDemo.LombokDemoBuilder id(Integer id) {
this.id = id;
return this;
}

public LombokDemo.LombokDemoBuilder name(String name) {
this.name = name;
return this;
}

public LombokDemo build() {
return new LombokDemo(this.id, this.name);
}

public String toString() {
return "LombokDemo.LombokDemoBuilder(id=" + this.id + ", name=" + this.name + ")";
}
}
}

@Delegate

  • 功能

@Delegate 注释的属性,会把这个属性对象的公有非静态方法合到当前类

  • 注意

公共 非静态方法

  • 源码
1
2
3
4
5
6
public class LombokDemo {

@Delegate
private Integer id;
private String name;
}
  • 编译后
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
27
28
29
30
31
32
33
34
35
36
37
package xyz.mrwood.study.lombok;

public class LombokDemo {
private Integer id;
private String name;

public LombokDemo() {
}

public byte byteValue() {
return this.id.byteValue();
}

public short shortValue() {
return this.id.shortValue();
}

public int intValue() {
return this.id.intValue();
}

public long longValue() {
return this.id.longValue();
}

public float floatValue() {
return this.id.floatValue();
}

public double doubleValue() {
return this.id.doubleValue();
}

public int compareTo(Integer arg0) {
return this.id.compareTo(arg0);
}
}

工具相关

@Cleanup

  • 功能

关闭流

  • 注意

关闭流的方式有点怪异,而且没有在finally里面关闭,如果出现异常的就不会关闭了

  • 源码
1
2
3
4
5
6
7
8
9
public class LombokDemo {

public void test() throws IOException {

@Cleanup InputStream inputStream = new FileInputStream("xxx.txt");

}

}
  • 编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package xyz.mrwood.study.lombok;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Collections;

public class LombokDemo {
public LombokDemo() {
}

public void test() throws IOException {
FileInputStream inputStream = new FileInputStream("xxx.txt");
if(Collections.singletonList(inputStream).get(0) != null) {
inputStream.close();
}

}
}

@Synchronized

  • 功能

给方法加一个同步块

  • 源码
1
2
3
4
5
6
7
8
9
10
public class LombokDemo {

@Synchronized
public void test() throws IOException {

System.out.println("test");

}

}
  • 编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package xyz.mrwood.study.lombok;

import java.io.IOException;

public class LombokDemo {
private final Object $lock = new Object[0];

public LombokDemo() {
}

public void test() throws IOException {
Object var1 = this.$lock;
synchronized(this.$lock) {
System.out.println("test");
}
}
}

@SneakyThrows

  • 功能

忽略异常

  • 源码
1
2
3
4
5
6
7
8
9
10
public class LombokDemo {

@SneakyThrows
public void test() {

String s = new String("test".getBytes(), "utf-8");

}

}
  • 编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package xyz.mrwood.study.lombok;

import java.io.IOException;

public class LombokDemo {
private final Object $lock = new Object[0];

public LombokDemo() {
}

public void test() throws IOException {
Object var1 = this.$lock;
synchronized(this.$lock) {
System.out.println("test");
}
}
}

@NonNull

  • 功能

设置不能为空的参数

  • 源码
1
2
3
4
5
6
public class LombokDemo {

public void test(@NonNull String val) {

}
}
  • 编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package xyz.mrwood.study.lombok;

import lombok.NonNull;

public class LombokDemo {
public LombokDemo() {
}

public void test(@NonNull String val) {
if(val == null) {
throw new NullPointerException("val");
}
}
}

@UtilityClass

  • 功能

把普通类转为工具类

  • 源码
1
2
3
4
5
6
7
8
9
10
11
@UtilityClass
public class LombokDemo {

private Integer id = 1;
private String name = "kiwi";

public void util(){

System.out.println("xxx");
}
}
  • 编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package xyz.mrwood.study.lombok;

public final class LombokDemo {
private static Integer id = Integer.valueOf(1);
private static String name = "kiwi";

public static void util() {
System.out.println("xxx");
}

private LombokDemo() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}

本文地址 https://blog.coder4j.cn/posts/e36fd55e/