非常实用的Java工具类库

文章是从公众号《猫玛尼》迁移过来,内容稍有调整。


给大家强烈推荐一个非常实用的Java工具类库——Lombok,它可以有效地减少Java代码的冗长,让你的代码,看上去非常的简洁、优雅。

大家一般都是使用某个IDE(IDE是集成开发环境,它可以有效的提升我们的工作效率),来开发项目。要使用强大的Lombok,首先需要给你的IDE安装上相关的插件。

我平常用的是IntelliJ IDEA(下面都简称为IDEA),Lombok的安装步骤如下:

1、打开IntelliJ IDEA左上角的Preferences,选择Plugins,在搜索框中输入“Lombok”;

2、这个时候搜索结果里面可能没有,那就需要点击搜索结果里面蓝色字体的“Search in repositories”,就是通过在线仓库查找Lombok相关插件。点击超链接后,会弹出“Browse Repositories”在线搜索结果;

3、选中结果集中的“Lombok Plugin”,然后在右侧的插件介绍面板中点击“Install”,安装这个插件;

4、IDEA需要下载该插件,然后在后台安装,一般情况下都挺快的,一分钟不到吧。安装完成之后,刚才你点击的那个绿色的“Install”按钮,会变成“Restart IntelliJ IDEA”,点击这个按钮,重新启动IDEA,就OK了。我们可以去Plugins里面看一下,就能看到我们刚才安装的“Lombok Plugin”插件了。

img

安装好了插件,需要给项目引入Lombok依赖,可以直接下载Jar丢到你的项目里面,如果是Maven项目的话,可以在pom文件里面添加上依赖。我这边的例子是跑在Maven项目里的。

我一般是在

https://mvnrepository.com/”这个中心仓库里面查找我想要的各种依赖。这个中心仓库东西很全。在中心仓库里面搜索“Lombok”,结果里的第一个就是,然后点进去选择具体的版本,我一般会选择使用最多的那个版本,这里是“1.18.2”:

img

把依赖文本复制到我们的pom.xml文件里面,然后“import Changes”,把依赖真正的加到我们项目里面去就OK了:

img

接下去就可以尽情的使用Lombok工具类库了。一个简单的例子如下:

img

看例子,能够很明显的感觉到,所写的代码非常简洁、清晰,少了大量的getter、setter、构造器等代码。

一般都是通过注解的方式使用Lombok,简单介绍一下常用的一些注解:

@Data注解:为Java类的所有字段生成getter、一个有用的toString方法和hashCode。还会为所有非final字段生成setter。该注解的作用等同于:@Getter、@Setter、@RequiredArgsConstructor、@ToString、@EqualsAndHashCode一起使用。

@Getter/@Setter注解:给相应的字段加上getter/setter方法,可以用在类或字段上。在类上面,标注这两个注解,表示该类中所有的非静态字段,都会生成相应的getter/setter方法;在字段上标注,则表示只给这个字段生成getter/setter方法,两者都有,则以标注在字段上优先。@Setter注解对final字段失效。

@ToString注解:只能标注在类上,给类生成一个具有一定可读性的toString()方法。

@NoArgsConstructor注解:给类生成一个无参构造器。

@AllArgsConstructor注解:给类生成一个包含所有字段的构造器。

@Builder注解:给类赋予了builder模式(建造者模式)。它可以解决字段很多的类重载多个构造器的繁琐,同时链式调用简化了类的构造。例子中“小码哥”那部分代码片段用到的就是这种模式。

@NonNull注解:可以标注在方法的参数上面。如果标注的这个参数,调用的时候传过来的值为null,则会抛出NPE(空指针异常),这样就不需要在代码中判空了,非常的方便。

@Log注解:可以给类添加一个日志对象log,使用的时候直接log.info(“some info”)就行,非常的方便。它使用的是Java自带的日志框架,该对象的类型是java.util.logging.Logger。

@Slf4j注解:它也用于记录日志,关于日志,我基本用的是这个注解。全称是simple logging facade for java,是Java的简单的日志门面。它不是具体的日志解决方案,它只服务于各种各样slf4j-logo的日志系统,比如Java自己的日志系统、Log4j、Log4j2、logback、JBossLog等,用Slf4j可以用统一的风格,编写日志代码。以后切换日志系统,也不需要修改任何代码。

还有其他的一些注解,我不太常用,大家有兴趣的也可以去研究一下,比如:@NonFinal、@PackagePrivate、@SuperBuilder、@Wither、@Singular、@Synchronized、@Value、@SneakyThrows等等,具体可以去官网查看他们的使用方法或直接在Jar包里面看代码。官网是:https://www.projectlombok.org/

有想法的开发者,可能会想,这一切,Lombok是怎么实现的呢?

万变不离其宗,就算工具在我们编写代码的这一步做了手脚,编译后的代码还是会还原最真实的面貌。编译后的代码,如下图:

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
package com.mmn.sum.example;

import java.util.ArrayList;
import java.util.List;

public class LombokUser {
private String name;
private Integer age;
private List<String> hobby;

public static void main(String[] args) {
LombokUser anonymous = new LombokUser();
System.out.println(anonymous);
List<String> mmnHobby = new ArrayList();
mmnHobby.add("打代码");
LombokUser mmn = new LombokUser("猫玛尼", 27, mmnHobby);
System.out.println(mmn);
List<String> littleZHobby = new ArrayList();
littleZHobby.add("吃东西");
LombokUser littleZ = new LombokUser();
littleZ.setAge(18);
littleZ.setName("小张");
littleZ.setHobby(littleZHobby);
System.out.println(littleZ);
LombokUser xmg = builder().age(36).name("小码哥").hobby(new ArrayList()).build();
System.out.println(xmg);
}

public static LombokUser.LombokUserBuilder builder() {
return new LombokUser.LombokUserBuilder();
}

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

public Integer getAge() {
return this.age;
}

public List<String> getHobby() {
return this.hobby;
}

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

public void setAge(Integer age) {
this.age = age;
}

public void setHobby(List<String> hobby) {
this.hobby = hobby;
}

public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof LombokUser)) {
return false;
} else {
LombokUser other = (LombokUser)o;
if (!other.canEqual(this)) {
return false;
} else {
label47: {
Object this$name = this.getName();
Object other$name = other.getName();
if (this$name == null) {
if (other$name == null) {
break label47;
}
} else if (this$name.equals(other$name)) {
break label47;
}

return false;
}

Object this$age = this.getAge();
Object other$age = other.getAge();
if (this$age == null) {
if (other$age != null) {
return false;
}
} else if (!this$age.equals(other$age)) {
return false;
}

Object this$hobby = this.getHobby();
Object other$hobby = other.getHobby();
if (this$hobby == null) {
if (other$hobby != null) {
return false;
}
} else if (!this$hobby.equals(other$hobby)) {
return false;
}

return true;
}
}
}

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

public int hashCode() {
int PRIME = true;
int result = 1;
Object $name = this.getName();
int result = result * 59 + ($name == null ? 43 : $name.hashCode());
Object $age = this.getAge();
result = result * 59 + ($age == null ? 43 : $age.hashCode());
Object $hobby = this.getHobby();
result = result * 59 + ($hobby == null ? 43 : $hobby.hashCode());
return result;
}

public String toString() {
return "LombokUser(name=" + this.getName() + ", age=" + this.getAge() + ", hobby=" + this.getHobby() + ")";
}

public LombokUser() {
}

public LombokUser(String name, Integer age, List<String> hobby) {
this.name = name;
this.age = age;
this.hobby = hobby;
}

public static class LombokUserBuilder {
private String name;
private Integer age;
private List<String> hobby;

LombokUserBuilder() {
}

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

public LombokUser.LombokUserBuilder age(Integer age) {
this.age = age;
return this;
}

public LombokUser.LombokUserBuilder hobby(List<String> hobby) {
this.hobby = hobby;
return this;
}

public LombokUser build() {
return new LombokUser(this.name, this.age, this.hobby);
}

public String toString() {
return "LombokUser.LombokUserBuilder(name=" + this.name + ", age=" + this.age + ", hobby=" + this.hobby + ")";
}
}
}

我们可以清楚的看到,编译后的代码,比原来多了很多的Getter、Setter,还有equals、LombokUserBuilder等。

我们做技术的,在个人能力没有触达的地方,可以通过强大的Google、Baidu来借助高人。

我翻阅了一些资料,原来 Lombok实现了JSR 269 API,即插入式注解处理API。它提供了一套标准API来处理Annotations,我们可以利用JSR 269提供的API来构建一个功能丰富的元编程(metaprogramming)环境。有兴趣的同学,可以自行深入研究。

用起来很简单,但是背后的设计思想还是很厉害的。

感谢高人,为我们提供了这么好的工具类库~

【我平时的开发环境】

饭碗:Mac Pro 13寸

IDE:IntelliJ IDEA 2018

JDK:8

打包:Maven 3

------------- 本文结束感谢阅读 -------------
给猫玛尼加个鸡腿~