Java 开发工具–Lombok介绍
来源:互联网 发布:美国硕士一年花费知乎 编辑:程序博客网 时间:2024/06/06 03:49
Java 开发工具–Lombok介绍
问题描述
在写POJO代码时,经常需要生成getter和setter方法,以及hashcode、tostring和equals等代码。感觉甚是麻烦,虽然有Eclipse或者intellij IDEA快捷键帮我们自动生成些代码,但感觉还是麻烦(其实就是懒)。
偶然中,得知Lombok Project,通过使用注解,可以消除冗余的java代码。
官网的介绍:Project Lombok makes java a spicier language by adding ‘handlers’ that know >how to build and compile simple, boilerplate-free, not-quite-java code.
如何使用
如果是maven管理的项目,通过引入dependency即可:
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.12</version> <scope>provided</scope></dependency>
Gradle项目的引入方式类似:
provided group: 'org.projectlombok', name: 'lombok', version: '1.16.18'
另外,在spring boot项目中,引入Lombok时没有必要指定和,因为 spring boot 已经帮我们自动配置好。
如何安装
先说IDEA,在IDEA中安装Lombok需要先安装插件,快捷键 Ctrl + Alt + S,然后选择 plugins——> browse repositories,搜索 Lombok,install即可,安装需要重启。
其次,Lombok是在编译时期,自动生成所需方法的,所以需要开启annotation processing;依旧是刚才的快捷键,可以搜索”annotation processing”,然后选择”Enable annotation processing”.
如果是Eclipse的话,官网下载最新的Lombok.jar,双击或者`java -jar lombok.jar
在弹出的窗口,确认刚才 Lombok 扫描整个硬盘得到的Eclipse安装程序结果即可(Eclipse,MyEclipse,STS(Spring tool suite)),点击 Install/Update。
注解
刚才提到,Lombok是通过注解来减少编码的,那都提供哪些注解呢?
不完全统计:
@NonNull:标识对象是否为空,为空则抛出异常@Getter/@Setter:自动生成Getter/Setter方法@ToString:覆盖tostring方法,可以添加限制条件@EqualsAndHashCode:覆盖equal和hashCode方法,生成方法时只会使用类中的非静态和非transient成员变量@Data:@Getter/@Setter, @ToString, @EqualAndHashCode,@AllArgsConstructor等组合@Cleanup:用在变量前面,可以保证此变量代表的资源会被自动关闭,默认是调用资源的close()方法,如果该资源有其它关闭方法,可使用@Cleanup(“methodName”)来指定要调用的方法@NoArgsConstructor/@RequiredArgsConstructor /@AllArgsConstructor:第二个注解使用类中所有带有@NonNull注解的或带有final修饰的非静态成员变量生成对应的构造方法,@Log:类注解,可以省去从日志工厂生成日志对象这一步,直接进行日志记录,具体注解根据日志工具的不同而不同,同时,可以在注解中使用topic来指定生成log对象时的类名@Builder:关于build模式,可以参考《Effective java》这本书@Value@SneakyThrows@Synchronized
实例代码判断
上面的注解简介太模糊?看看实例:
1 @Getter & @Setter & @ToString
public class Person { private boolean employed; private String name; Person() { } public String say() { return this.getName(); } public String toString() { return "Person(employed=" + this.isEmployed() + ", name=" + this.getName() + ")"; } public boolean isEmployed() { return this.employed; } public void setEmployed(boolean employed) { this.employed = employed; } public String getName() { return this.name; } protected void setName(String name) { this.name = name; }}
如果使用Lombok提供的注解:
@ToString class Person { @Getter @Setter private boolean employed; @Getter @Setter(AccessLevel.PROTECTED) private String name; public String say() { return getName(); }}
2. @Builder
这次先看看使用注解之前的java code:
@Builderpublic class BuilderExample { private String name; private int age;}
再看看其经过编译之后的java code:
import java.beans.ConstructorProperties;public class BuilderExample { private String name; private int age; @ConstructorProperties({"name", "age"}) BuilderExample(String name, int age) { this.name = name; this.age = age; } public static BuilderExample.BuilderExampleBuilder builder() { return new BuilderExample.BuilderExampleBuilder(); } public static class BuilderExampleBuilder { private String name; private int age; BuilderExampleBuilder() { } public BuilderExample.BuilderExampleBuilder name(String name) { this.name = name; return this; } public BuilderExample.BuilderExampleBuilder age(int age) { this.age = age; return this; } public BuilderExample build() { return new BuilderExample(this.name, this.age); } public String toString() { return "BuilderExample.BuilderExampleBuilder(name=" + this.name + ", age=" + this.age + ")"; } }}
3. @Data
先看使用注解的类:
@Datapublic class User { private Integer id; private String password;}
编译之后的类长这样:
public class User { private Integer id; private String password; public User() { } public Integer getId() { return this.id; } public String getPassword() { return this.password; } public void setId(Integer id) { this.id = id; } public void setPassword(String password) { this.password = password; } public boolean equals(Object o) { if (o == this) { return true; } else if (!(o instanceof User)) { return false; } else { User other = (User)o; if (!other.canEqual(this)) { return false; } else { Object this$id = this.getId(); Object other$id = other.getId(); if (this$id == null) { if (other$id != null) { return false; } } else if (!this$id.equals(other$id)) { return false; } Object this$password = this.getPassword(); Object other$password = other.getPassword(); if (this$password == null) { if (other$password != null) { return false; } } else if (!this$password.equals(other$password)) { return false; } return true; } } } protected boolean canEqual(Object other) { return other instanceof User; } public int hashCode() { int PRIME = true; int result = 1; Object $id = this.getId(); int result = result * 59 + ($id == null ? 43 : $id.hashCode()); Object $password = this.getPassword(); result = result * 59 + ($password == null ? 43 : $password.hashCode()); return result; } public String toString() { return "User(id=" + this.getId() + ", password=" + this.getPassword() + ")"; }}
更多注解的用法,感兴趣的话,请参考官网。
Lombok原理
采用JSR269所提出的插入式注解处理(Pluggable Annotation Processing),并结合动态代码生成技术所开发的。如下图所示:
图示为 javac 的编译过程,java文件首先通过进行解析构建出一个AST,然后执行注解处理,最后经过分析优化生成二进制的.class文件。
Annotation Processing 是在解析和生成之间的一个步骤。
上图是 Lombok 处理流程,在Javac 解析成抽象语法树之后(AST),Lombok 根据自己的注解处理器,动态的修改 AST,增加新的节点(所谓代码),最终通过分析和生成字节码。
Lombok缺点
这么好的工具,那可以应用到生产环境吗?真不一定,Lombok 注解的引入一定程度上会造成源码的可读性(不是所有人都了解其使用)和完整性,而且生成环境使用,不一定还会遇到什么坑,看看其代码托管GitHub的issue就知道。
不过反过来一想,issue 开得多,不正说明其应用还是很广泛的?
参考
基本实现原理
jdk-compilation-overview
- Java 开发工具–Lombok介绍
- Java开发工具之Lombok
- [JAVA]探测 Lombok 工具
- Java工具库之Lombok
- Java开发工具介绍
- Java开发工具介绍
- Java开发工具介绍
- Java开发工具介绍
- java 开发工具介绍
- Java【老司机专属 Lombok超便捷工具介绍及使用方法】
- Lombok工具
- Lombok介绍
- lombok介绍
- Lombok简化Java代码的好工具
- Lombok 介绍 消除Java的冗长
- java开发工具简单介绍
- 【转】Java开发工具介绍
- Java常用开发工具介绍
- C判断char型和unsigned int型比较大小,LmiQueryCSmd
- 002day(学习了二进制和十六进制的基本概念)
- OpenMV色块定位-电赛的半个总结
- ThreadLocal类
- Android 悬浮窗踩坑体验
- Java 开发工具–Lombok介绍
- linux chmod和文件权限的设定
- php学习笔记:登录练习(3)
- 2.2.16锁对象的改变
- C语言中使用空的宏定义的作用
- 高斯消元法
- Netty源码分析:AbstractByteBuf
- Servlet 工程 web.xml 中的 servlet 和 servlet-mapping 标签
- 利用分治法实现逆序数对的求解