Lombok简介
Lombok是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具,通过使用对应的注解,可以在编译源码的时候生成对应的方法。官方地址:https://projectlombok.org/,github地址:https://github.com/rzwitserloot/lombok。
注解介绍
下面只是介绍了几个常用的注解,更多的请参见https://projectlombok.org/features/index.html。
@Data
@Data注解在类上,会为类的所有属性自动生成setter/getter、equals、canEqual、hashCode、toString方法,如为final属性,则不会为该属性生成setter方法。
@Getter / @Setter
可以作用在类上和属性上,放在类上,会对所有的非静态(non-static)属性生成Getter/Setter方法,放在属性上,会对该属性生成Getter/Setter方法。并可以指定Getter/Setter方法的访问级别。
@NonNull
该注解用在属性或构造器上,Lombok会生成一个非空的声明,可用于校验参数,能帮助避免空指针。
@Cleanup
该注解能帮助我们自动调用close()方法,很大的简化了代码。
@EqualsAndHashCode
默认情况下,会使用所有非瞬态(non-transient)和非静态(non-static)字段来生成equals和hascode方法,也可以指定具体使用哪些属性。
@ToString
类使用@ToString注解,Lombok会生成一个toString()方法,默认情况下,会输出类名、所有属性(会按照属性定义顺序),用逗号来分割。
@NoArgsConstructor
注解在类上,为类提供一个无参的构造方法。
注意:
当类中有final字段没有被初始化时,编译器会报错,此时可用@NoArgsConstructor(force = true),然后就会为没有初始化的final字段设置默认值0/ false / null。
对于具有约束的字段(例如@NonNull字段),不会生成检查或分配,因此请注意,正确初始化这些字段之前,这些约束无效。
@AllArgsConstructor
(1)注解在类上,为类提供一个全参的构造方法。
(2)默认生成的方法是 public 的,如果要修改方法修饰符可以设置 AccessLevel 的值。
@RequiredArgsConstructor
(1)注解在类上,会生成构造方法(可能带参数也可能不带参数)。
注意:如果带参数,这参数只能是以 **final** 修饰的未经初始化的字段或者是以 **@NonNull** 注解的未经初始化的字段。
(2)该注解还可以用 @RequiredArgsConstructor(staticName=“methodName”) 的形式生成一个指定名称的静态方法,返回一个调用相应的构造方法产生的对象
Lombok原理
了解了简单的使用之后,现在应该比较好奇它是如何实现的。整个使用的过程中,只需要使用注解而已,不需要做其它额外的工作,那玄妙之处应该是在注解的解析上。JDK5引入了注解的同时,也提供了两种解析方式。
运行时解析
运行时能够解析的注解,必须将@Retention设置为RUNTIME,这样可以通过反射拿到该注解。java.lang.reflect反射包中提供了一个接口AnnotatedElement,该接口定义了获取注解信息的几个方法,Class、Constructor、Field、Method、Package等都实现了该接口,大部分开发者应该都很熟悉这种解析方式。
编译时解析
Annotation Processing Tool
apt自JDK5产生,JDK7已标记为过期,不推荐使用,JDK8中已彻底删除,自JDK6开始,可以使用Pluggable Annotation Processing API来替换它,apt被替换主要有2点原因:
- api都在com.sun.mirror非标准包下
- 没有集成到javac中,需要额外运行
apt的更多介绍可以参见这里。
Pluggable Annotation Processing API
JSR 269,自JDK6加入,作为apt的替代方案,它解决了apt的两个问题,javac在执行的时候会调用实现了该API的程序,这样我们就可以对编译器做一些增强,这时javac执行的过程如下:
Lombok本质上就是一个实现了“JSR 269 API”的程序。在使用javac的过程中,它产生作用的具体流程如下:
-
javac对源代码进行分析,生成了一棵抽象语法树(AST)
-
运行过程中调用实现了“JSR 269 API”的Lombok程序
-
此时Lombok就对第一步骤得到的AST进行处理,找到@Data注解所在类对应的语法树(AST),然后修改该语法树(AST),增加getter和setter方法定义的相应树节点
-
javac使用修改后的抽象语法树(AST)生成字节码文件,即给class增加新的节点(代码块)
Lombok无法支持多种参数构造器的重载
相应树节点
- javac使用修改后的抽象语法树(AST)生成字节码文件,即给class增加新的节点(代码块)
Lombok无法支持多种参数构造器的重载
想了解更多详情请点击查看