最近有小伙伴跟我讲,“搞了5年Java ,太累了,写的代码又臭又长,每天都要写一堆getter 和setter ”
我对他讲,还不快尝试一下Lombok ,这可是炙手可热的大杀器啊,保准让你用了停不下来!
下面我就简单介绍下Lombok 有哪些妙处!
简介
Lombok 是一个编译级别的插件,它可以在项目编译的时候生成一些代码。通俗的说,Lombok 可以通过注解在编译器自动生成getter settter 等代码,让我们的代码瞬间变得清爽。
有些人不提倡使用Lombok ,认为Lombok 对代码侵入性太强了,强制整个小组都要使用Lombok ,不装,项目就跑不起来。
我想说,你装下,就知道多简单了。2分钟,换来永远的快活,它不香吗?
安装
这里使用Gradle 6.3.8 演示
添加依赖
compileOnly("org.projectlombok:lombok:1.18.12")
annotationProcessor("org.projectlombok:lombok:1.18.12")
安装插件
1、打开IDEA 的插件页,搜索Lombok ,点击安装
2、配置
这里要注意的是,如果你使用的是Gradle 高版本(>= 5.0),不需要勾选启用注解处理 ,如果低于5.0 版本,则必须勾选此项。
到这就已经配置好了,是不是超简单?别告诉我你花了超过2分钟!
接下来,就让我们体验一下Lombok 的妙处!
使用
我把Lombok 生成的源代码都给你列出来了,你还不放心吗?
@NonNull
标记字段不可为null
@Setter
public class Person {
@NonNull
private String name;
@NonNull
private Integer age;
}
对应的字节码反编译文件:
public class Person {
@NonNull
private String name;
@NonNull
private Integer age;
public Person() {
}
public void setName(@NonNull String name) {
if (name == null) {
throw new NullPointerException("name");
} else {
this.name = name;
}
}
public void setAge(@NonNull Integer age) {
if (age == null) {
throw new NullPointerException("age");
} else {
this.age = age;
}
}
}
@Getter/@Setter
自动生成getter 和setter 方法
public class Person {
@Getter
private String name;
@Setter
private Integer age;
}
对应的字节码反编译文件:
public class Person {
private String name;
private Integer age;
public Person() {
}
public String getName() {
return this.name;
}
public void setAge(Integer age) {
this.age = age;
}
}
@Cleanup
自动关闭流代码
@Cleanup
InputStream in = new FileInputStream(args[0]);
对应的字节码文件:
InputStream in = new FileInputStream(args[0]);
if (Collections.singletonList(in).get(0) != null) {
in.close();
}
@AllArgsConstructor/@NoArgsConstructor/@RequiredArgsConstructor
自动生成全参构造函数和无参构造函数
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private String name;
private Integer age;
}
对应的字节码反编译文件
public class Person {
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public Person() {
}
}
@Builder
自动生成建造者模式的bean
@Builder
public class Person {
private String name;
private Integer age;
}
对应的字节码反编译文件
public class Person {
private String name;
private Integer age;
Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public static Person.PersonBuilder builder() {
return new Person.PersonBuilder();
}
public static class PersonBuilder {
private String name;
private Integer age;
PersonBuilder() {
}
public Person.PersonBuilder name(String name) {
this.name = name;
return this;
}
public Person.PersonBuilder age(Integer age) {
this.age = age;
return this;
}
public Person build() {
return new Person(this.name, this.age);
}
public String toString() {
return "Person.PersonBuilder(name=" + this.name + ", age=" + this.age + ")";
}
}
}
@EqualsAndHashCode
自动生成equals 和hashcode 方法
@EqualsAndHashCode
public class Person {
private String name;
private Integer age;
}
对应的字节码反编译文件
public class Person {
private String name;
private Integer age;
public Person() {
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Person)) {
return false;
} else {
Person other = (Person)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$name = this.name;
Object other$name = other.name;
if (this$name == null) {
if (other$name != null) {
return false;
}
} else if (!this$name.equals(other$name)) {
return false;
}
Object this$age = this.age;
Object other$age = other.age;
if (this$age == null) {
if (other$age != null) {
return false;
}
} else if (!this$age.equals(other$age)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(Object other) {
return other instanceof Person;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $name = this.name;
int result = result * 59 + ($name == null ? 43 : $name.hashCode());
Object $age = this.age;
result = result * 59 + ($age == null ? 43 : $age.hashCode());
return result;
}
}
@ToString
自动生成toString() 方法
@ToString
public class Person {
private String name;
private Integer age;
}
对应的字节码反编译文件
public class Person {
private String name;
private Integer age;
public Person() {
}
public String toString() {
return "Person(name=" + this.name + ", age=" + this.age + ")";
}
}
@Value
自动生成全参构造函数、Getter 方法、equals 方法、hashCode 方法、toString 方法
@Value
public class Person {
private String name;
private Integer age;
}
注意:@Value 不会生成Setter 方法
@Synchronized
自动为被标记的方法添加synchronized 锁
谨慎使用,出了问题我可不负责!
public class SynchronizedExample {
private final Object readLock = new Object();
@Synchronized
public static void hello() {
System.out.println("world");
}
@Synchronized
public int answerToLife() {
return 42;
}
@Synchronized("readLock")
public void foo() {
System.out.println("bar");
}
}
对应的字节码反编译文件
public class SynchronizedExample {
private static final Object $LOCK = new Object[0];
private final Object $lock = new Object[0];
private final Object readLock = new Object();
public static void hello() {
synchronized($LOCK) {
System.out.println("world");
}
}
public int answerToLife() {
synchronized($lock) {
return 42;
}
}
public void foo() {
synchronized(readLock) {
System.out.println("bar");
}
}
}
@Delegate
为标记属性生成委托方法,例如在适配器模式下,我们就可以使用此注解简化我们的实现。
public class DelegateExample {
public void show() {
System.out.println("show...");
}
}
@AllArgsConstructor
public class Demo {
@Delegate
private final DelegateExample delegateExample;
}
对应的字节码反编译文件
public class DelegateExample {
public DelegateExample() {
}
public void show() {
System.out.println("show...");
}
}
public class Demo {
private final DelegateExample delegateExample;
public Demo(DelegateExample delegateExample) {
this.delegateExample = delegateExample;
}
public void show() {
this.delegateExample.show();
}
}
今天就介绍这么多,下次再聊聊Lombok 的高级技巧!
我是阿晨,在技术的道路上我们一起砥砺前行!
|