lombok安装
idea插件安装
打开 IDEA 的 Settings 面板,并选择 Plugins 选项,然后点击 “Browse repositories”
在输入框输入”lombok”,得到搜索结果,点击安装,然后安装提示重启 IDEA,安装成功;
[外链图片转存失败(img-Pg4jcaSi-1565399114074)(evernotecid://CD8D29A3-4674-4DAF-91D6-5E8332FBECE8/appyinxiangcom/12451481/ENResource/p110)]
maven依赖引入
在自己的项目里添加 lombok 的编译支持,在 pom 文件里面添加 dependency
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.0</version>
</dependency>
lombok使用
类构造注解
@AllArgsConstructor(staticName = "getInstance"
,access = AccessLevel.PRIVATE,
onConstructor_ = {@SneakyThrows(Exception.class)})
@RequiredArgsConstructor(access = AccessLevel.PUBLIC)
@NoArgsConstructor(access = AccessLevel.PRIVATE,
force = true)
public class ArgumentUser {
private final String firstName;
private final String lastName;
private static int age;
private final String phone;
private final String address;
public static void main(String[] args) {
}
}
staticName:私有化生产的构造器并生成一个静态构造方法
access:设置生成的构造器的可见性
onConstructor:在生成的构造器上增加其他注解
force:为true时,初始化所有静态属性到0/false/null
注解(位置TYPE)/属性 | staticName | onConstructor | access | force |
---|---|---|---|---|
@AllArgsConstructor | 1 | 1 | 1 | 0 |
@RequiredArgsConstructor | 1 | 1 | 1 | 0 |
@NoArgsConstructor | 1 | 1 | 1 | 1 |
@AllArgsConstructor
生成一个全参数构造函数.
@RequiredArgsConstructor
生成一个以所有final字段和@NonNull标注的字段为形参的构造函数。
@NoArgsConstructor
自动生成一个无参构造函数。如果类含有final字段,会出现编译错误,通过指定属性force为true,为final字段进行初始化。
构造者模式
@Builder(builderClassName = "UserBuilder",
builderMethodName = "abc",
buildMethodName = "userBuild",
toBuilder = true)
@ToString
public class LombokUser {
@Singular
private List<String> histories;
@Builder.Default
private String firstName;
private String lastName;
private final int age = 13;
private String phone;
@Builder.ObtainVia(field = "address")
private String address;
}
@Builder
builderClassName:自定义建造类(TypeName)Builder的类名
builderMethodName:自定义builder()的方法名
buildMethodName:自定义build()的方法名
toBuilder:克隆一个旧的builder
@Builder.ObtainVia
该注解的作用是标明一个字段获取值的方式。详情对应下面参数:
field:使用this.field赋值
method:使用this.method()赋值
isStatic:使用SelfType.method(this)赋值,要求mthod是静态的
@Builder.Default(FIELD)
该注解标明一个字段的默认值。
@Singular
该注解标明一个集合类型的字段赋值允许一个一个的赋值。
ps:字段名注意为复数,否则报错
类属性
@Data
@Getter
@Setter
@EqualsAndHashCode
public class FieldUser {
private List<String> histories;
private String firstName;
private String lastName;
private final int age = 13;
private String phone;
private String address;
}
@Getter(TYPE,FIELD)
自动生成标准的getter方法
lazy:默认false,不可用
onMethod:在方法上增加其他注解
value:设置方法的可见性
@Setter(TYPE,FIELD)
自动生成标准的setter方法
onParam:在方法参数上增加其他注解
onMethod:同@Getter.onMethod
value:同@Getter.value
@EqualsAndHashCode(TYPE)
利用父类方法和相关属性生成equals()和hashCode()
callSuper:在使用本类属性前先使用父类方法计算
doNotUseGetters:不使用getter方法
exclude:计算时不使用这里罗列的属性
of:计算时使用这里罗列的属性
onParam:同@Setter.onParam
@ToString(TYPE)
利用父类方法和相关属性生成toString()方法,方便日志打印。
@Data(TYPE)
@Getter/@Setter,@ToString,@EqualsAndHashCode和@RequiredArgsConstructor组合的便捷写法
staticConstructor:同@RequiredArgsConstructor.staticName
日志
@Slf4j
public class LombokLog {
public void execute() {
log.info("this is log test");
}
}
@CommonsLog
@Log
@JBossLog
@Log4j
@Log4j2
@Slf4j
@Slf4j2
其他
public class LombokOther {
@NonNull
private List<String> histories;
@
private String firstName;
private String lastName;
private final int age = 13;
private String phone;
private String address;
@Synchronized @SneakyThrows({FileNotFoundException.class, MalformedURLException.class, IOException.class})
public void execute(@NonNull String string) {
@Cleanup @NonNull
InputStream inputStream = new FileInputStream("");
}
}
@NonNull
(FIELD,METHOD,PARAMETER,LOCAL_VARIABLE)
自动生成引用空检查代码,为空时抛出空指针异常
@SneakThrows(METHOD,CONSTRUCTOR)
自动生成代码,抛出受检异常
@Synchronized(METHOD)
被标注的方法使用生成的锁对象( l o c k 和 lock和 lock和Lock)而非默认的(this和SlefType)
@Value(TYPE)
便捷地转化可变类到不可变
@Cleanup(LOCAL_VARIABLE)
生成自动关闭资源的代码
var val
val 便捷地声明final局部变量的类型(主要用于含有类型推断的情况)
val的非final情况
原理
在介绍lombok使用过程中,可以了解到,在项目中要使用lombok,需要添加两部分东西,第一是插件(lombokplugin),第二在pom文件中添加依赖包。
插件的作用
首先来说说lombokplugin插件的作用,该插件主要的功能是抑制idea监测的报错,增加代码跟踪功能。这个和idea软件功能相关,不细说,做简单的演示。
依赖包的作用
这个依赖包也是实现的关键。主要用到的技术是注解和插入式注解器。它主要的原理是在项目有.java文件编译成.class文件的过程中做手脚,实现一个接口AbstractProcessor,该接口可以让你在编译的过程中修改class文件,增加一些方法之类的。具体看代码。
注解
target
@target 描述了注解修饰的对象范围,取值在java.lang.annotation.ElementType定义,包括:
ANNOTATION_TYPE: 用于描述注解类型
CONSTRUCTOR:用于描述
FIELD: 作用于字段
LOCAL_VARIABLE:用于描述局部变量
METHOD:用于描述方法
PACKAGE:用于描述包
PARAMETER:用于描述方法变量
TYPE:用于描述类,接口或者enum类型
Retention
标明一个这个注解停留时间的长短,有些注解仅仅只在源码中,在编译的过程中被丢弃;另外一些可能会被一起编译进去class文件中,编译进去class文件中的注解可能被jvm虚拟机忽略,也可能会在class文件被装载时读取使用。其取值在java.lang.annotation.RetentionPolicy中定义,包括:
source:源文件中有效
class:随源文件一起编译进去class文件中,运行时忽略
running:运行时有效
Documented
@Documented 表示使用该注解的元素应被javadoc或类似工具文档化,它应用于类型声明,类型声明的注解会影响客户端对注解元素的使用。如果一个类型声明添加了 Documented 注解,那么它的注解会成为被注解元素的公共API的一部分。
Inherited
@Inherited 表示一个注解类型会被自动继承,如果用户在类声明的时候查询注解类型,同时类声明中也没有这个类型的注解,那么注解类型会自动查询该类的父类,这个过程将会不停地重复,直到该类型的注解被找到为止,或是到达类结构的顶层(即Object)。
Native
@Native 作用在域上,用来表示域中的常量可能来自于本地代码。
Repeatable
@Repeatable 表示一个注解是可重复的,适用于需要对同一个生命或类型加上相同注解(包含不同属性值)的情况。在之前版本的JDK中不允许再同一个声明前加同样的注解,@Repeatable 则可以帮助打破这种限制。举例来说明,假设有个权限系统,其中某个权限可能适用于多个角色成员。
jsr(插入式注解处理器)
ast(编译原理相关)
JSR269 api
AST(抽象语法树)
ASM