Lombok
作用:帮使用者提高编码效率,减少重复与冗余的代码
原理:ASM 动态修改class文件
配置
maven
依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.8</version>
</dependency>
编译
<build>
<plugins>
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.16.6.1</version>
</plugin>
</plugins>
</build>
idea
- 安装插件
常用注解:
java bean相关
@Setter
功能
生成setter方法
源码
@Setter
public class LombokDemo {
private Integer id;
private String name;
}
编译后
package xyz.mrwood.study.lombok;
public class LombokDemo {
private Integer id;
private String name;
public LombokDemo() {
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
@Getter
功能
生成getter方法
源码
@Getter
public class LombokDemo {
private Integer id;
private String name;
}
编译后
package xyz.mrwood.study.lombok;
public class LombokDemo {
private Integer id;
private String name;
public LombokDemo() {
}
public Integer getId() {
return this.id;
}
public String getName() {
return this.name;
}
}
@ToString
功能
生成toString方法
源码
@ToString
public class LombokDemo {
private Integer id;
private String name;
}
编译后
package xyz.mrwood.study.lombok;
public class LombokDemo {
private Integer id;
private String name;
public LombokDemo() {
}
public String toString() {
return "LombokDemo(id=" + this.id + ", name=" + this.name + ")";
}
}
@Getter(lazy = true)
功能
懒加载属性
注意:
这个与上面@Getter不同,那个是修饰在类上的,也可以修饰在属性上。如果有lazy=true只能修饰在属性,并且还要是private final修饰,限制很大
编码
public class LombokDemo {
@Getter(lazy = true) private final List<Integer> ids = Arrays.asList(1, 2, 3, 4);
private String name;
}
编译后
package xyz.mrwood.study.lombok;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
public class LombokDemo {
private final AtomicReference<Object> ids = new AtomicReference();
private String name;
public LombokDemo() {
}
public List<Integer> getIds() {
Object value = this.ids.get();
if(value == null) {
AtomicReference var2 = this.ids;
synchronized(this.ids) {
value = this.ids.get();
if(value == null) {
List actualValue = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4)});
value = actualValue == null?this.ids:actualValue;
this.ids.set(value);
}
}
}
return (List)((List)(value == this.ids?null:value));
}
}
@EqualsAndHashCode
功能
生成equals方法与hashCode方法
源码
@EqualsAndHashCode
public class LombokDemo {
private Integer id;
private String name;
}
编译后
package xyz.mrwood.study.lombok;
public class LombokDemo {
private Integer id;
private String name;
public LombokDemo() {
}
public boolean equals(Object o) {
if(o == this) {
return true;
} else if(!(o instanceof LombokDemo)) {
return false;
} else {
LombokDemo other = (LombokDemo)o;
if(!other.canEqual(this)) {
return false;
} else {
Integer this$id = this.id;
Integer other$id = other.id;
if(this$id == null) {
if(other$id != null) {
return false;
}
} else if(!this$id.equals(other$id)) {
return false;
}
String this$name = this.name;
String other$name = other.name;
if(this$name == null) {
if(other$name != null) {
return false;
}
} else if(!this$name.equals(other$name)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(Object other) {
return other instanceof LombokDemo;
}
public int hashCode() {
boolean PRIME = true;
byte result = 1;
Integer $id = this.id;
int result1 = result * 59 + ($id == null?43:$id.hashCode());
String $name = this.name;
result1 = result1 * 59 + ($name == null?43:$name.hashCode());
return result1;
}
}
@NoAragsConstructor
功能
添加一个无参构造函数
注意
这个注解在没有其它有参构造函数的情况下使用意义不大,因为在这种情况下java默认会添加一个无参构造函数
源码
@NoArgsConstructor
public class LombokDemo {
private Integer id;
private String name;
}
编译后
package xyz.mrwood.study.lombok;
public class LombokDemo {
private Integer id;
private String name;
public LombokDemo() {
}
}
@AllArgsConstructor
功能
添加一个所有参数的构造函数
源码
@AllArgsConstructor
public class LombokDemo {
private Integer id;
private String name;
}
编译后
package xyz.mrwood.study.lombok;
import java.beans.ConstructorProperties;
public class LombokDemo {
private Integer id;
private String name;
@ConstructorProperties({"id", "name"})
public LombokDemo(Integer id, String name) {
this.id = id;
this.name = name;
}
}
@RequiredArgsConstructor
功能
生成一个包含必填参数的构造函数
注意
要与@NonNull 搭配使用,该注解修饰的属性就是必填参数
源码
@RequiredArgsConstructor
public class LombokDemo {
@NonNull private Integer id;
private String name;
}
编译后
package xyz.mrwood.study.lombok;
import java.beans.ConstructorProperties;
import lombok.NonNull;
public class LombokDemo {
@NonNull
private Integer id;
private String name;
@ConstructorProperties({"id"})
public LombokDemo(@NonNull Integer id) {
if(id == null) {
throw new NullPointerException("id");
} else {
this.id = id;
}
}
}
@Data
功能
这是一个综合注解了,等于同时使用
@Getter
,@Setter
,@ToString
,@EqualsAndHashCode
,@RequiredArgsConstructor
源码
@Data
public class LombokDemo {
@NonNull private Integer id;
private String name;
}
编译后
package xyz.mrwood.study.lombok;
public class LombokDemo {
private Integer id;
private String name;
public LombokDemo() {
}
public Integer getId() {
return this.id;
}
public String getName() {
return this.name;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public boolean equals(Object o) {
if(o == this) {
return true;
} else if(!(o instanceof LombokDemo)) {
return false;
} else {
LombokDemo other = (LombokDemo)o;
if(!other.canEqual(this)) {
return false;
} else {
Integer this$id = this.getId();
Integer other$id = other.getId();
if(this$id == null) {
if(other$id != null) {
return false;
}
} else if(!this$id.equals(other$id)) {
return false;
}
String this$name = this.getName();
String other$name = other.getName();
if(this$name == null) {
if(other$name != null) {
return false;
}
} else if(!this$name.equals(other$name)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(Object other) {
return other instanceof LombokDemo;
}
public int hashCode() {
boolean PRIME = true;
byte result = 1;
Integer $id = this.getId();
int result1 = result * 59 + ($id == null?43:$id.hashCode());
String $name = this.getName();
result1 = result1 * 59 + ($name == null?43:$name.hashCode());
return result1;
}
public String toString() {
return "LombokDemo(id=" + this.getId() + ", name=" + this.getName() + ")";
}
}
@Value
功能
不可变类的@Data, 他会默认给属性加上final
源码
@Value
public class LombokDemo {
private Integer id;
private String name;
}
编译后
package xyz.mrwood.study.lombok;
import java.beans.ConstructorProperties;
public final class LombokDemo {
private final Integer id;
private final String name;
@ConstructorProperties({"id", "name"})
public LombokDemo(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return this.id;
}
public String getName() {
return this.name;
}
public boolean equals(Object o) {
if(o == this) {
return true;
} else if(!(o instanceof LombokDemo)) {
return false;
} else {
LombokDemo other = (LombokDemo)o;
Integer this$id = this.getId();
Integer other$id = other.getId();
if(this$id == null) {
if(other$id != null) {
return false;
}
} else if(!this$id.equals(other$id)) {
return false;
}
String this$name = this.getName();
String other$name = other.getName();
if(this$name == null) {
if(other$name != null) {
return false;
}
} else if(!this$name.equals(other$name)) {
return false;
}
return true;
}
}
public int hashCode() {
boolean PRIME = true;
byte result = 1;
Integer $id = this.getId();
int result1 = result * 59 + ($id == null?43:$id.hashCode());
String $name = this.getName();
result1 = result1 * 59 + ($name == null?43:$name.hashCode());
return result1;
}
public String toString() {
return "LombokDemo(id=" + this.getId() + ", name=" + this.getName() + ")";
}
}
@Accessors
功能
这个注解要搭配@Getter与@Setter使用,用来修改默认的setter与getter方法的形式
注意
@Accessors有三个参数可以使用
chain 链式的形式
fluent 流式的形式
prefix 生成指定前缀的属性的getter与setter方法,并且生成的getter与setter方法时会去除前缀
源码 chain = true
@Accessors(chain = true)
@Setter
@Getter
public class LombokDemo {
private Integer id;
private String name;
}
编译后 chain = true
package xyz.mrwood.study.lombok;
public class LombokDemo {
private Integer id;
private String name;
public LombokDemo() {
}
public LombokDemo setId(Integer id) {
this.id = id;
return this;
}
public LombokDemo setName(String name) {
this.name = name;
return this;
}
public Integer getId() {
return this.id;
}
public String getName() {
return this.name;
}
}
源码 fluent = true
@Accessors(fluent = true)
@Setter
@Getter
public class LombokDemo {
private Integer id;
private String name;
}
编译后 fluent = true
package xyz.mrwood.study.lombok;
public class LombokDemo {
private Integer id;
private String name;
public LombokDemo() {
}
public LombokDemo id(Integer id) {
this.id = id;
return this;
}
public LombokDemo name(String name) {
this.name = name;
return this;
}
public Integer id() {
return this.id;
}
public String name() {
return this.name;
}
}
源码 prefix = "xxx"
@Accessors(prefix = "xxx")
@Setter
@Getter
public class LombokDemo {
private Integer xxxId;
private String name;
}
编译后 prefix = "xxx"
package xyz.mrwood.study.lombok;
public class LombokDemo {
private Integer xxxId;
private String name;
public LombokDemo() {
}
public void setId(Integer xxxId) {
this.xxxId = xxxId;
}
public Integer getId() {
return this.xxxId;
}
}
其它注解:
日志相关
@Log4j
源码
@Log4j
public class LombokDemo {
private Integer xxxId;
private String name;
}
编译后
package xyz.mrwood.study.lombok;
import org.apache.log4j.Logger;
public class LombokDemo {
private static final Logger log = Logger.getLogger(LombokDemo.class);
private Integer xxxId;
private String name;
public LombokDemo() {
}
}
@CommonsLog
源码
@CommonsLog
public class LombokDemo {
private Integer xxxId;
private String name;
}
编译后
package xyz.mrwood.study.lombok;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class LombokDemo {
private static final Log log = LogFactory.getLog(LombokDemo.class);
private Integer xxxId;
private String name;
public LombokDemo() {
}
}
@Log
源码
@Log
public class LombokDemo {
private Integer xxxId;
private String name;
}
编译后
package xyz.mrwood.study.lombok;
import java.util.logging.Logger;
public class LombokDemo {
private static final Logger log = Logger.getLogger(LombokDemo.class.getName());
private Integer xxxId;
private String name;
public LombokDemo() {
}
}
@Log4j2
源码
@Log4j2
public class LombokDemo {
private Integer xxxId;
private String name;
}
编译后
package xyz.mrwood.study.lombok;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class LombokDemo {
private static final Logger log = LogManager.getLogger(LombokDemo.class);
private Integer xxxId;
private String name;
public LombokDemo() {
}
}
@Slf4j
源码
@Slf4j
public class LombokDemo {
private Integer xxxId;
private String name;
}
编译后
package xyz.mrwood.study.lombok;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LombokDemo {
private static final Logger log = LoggerFactory.getLogger(LombokDemo.class);
private Integer xxxId;
private String name;
public LombokDemo() {
}
}
设计模式相关
@Builder
功能
通过建造者模块来生成bean
源码
@Builder
public class LombokDemo {
private Integer id;
private String name;
}
编译后
package xyz.mrwood.study.lombok;
public class LombokDemo {
private Integer id;
private String name;
LombokDemo(Integer id, String name) {
this.id = id;
this.name = name;
}
public static LombokDemo.LombokDemoBuilder builder() {
return new LombokDemo.LombokDemoBuilder();
}
public static class LombokDemoBuilder {
private Integer id;
private String name;
LombokDemoBuilder() {
}
public LombokDemo.LombokDemoBuilder id(Integer id) {
this.id = id;
return this;
}
public LombokDemo.LombokDemoBuilder name(String name) {
this.name = name;
return this;
}
public LombokDemo build() {
return new LombokDemo(this.id, this.name);
}
public String toString() {
return "LombokDemo.LombokDemoBuilder(id=" + this.id + ", name=" + this.name + ")";
}
}
}
@Delegate
功能
@Delegate注释的属性,会把这个属性对象的公有非静态方法合到当前类
注意
公共 非静态方法
源码
public class LombokDemo {
@Delegate
private Integer id;
private String name;
}
编译后
package xyz.mrwood.study.lombok;
public class LombokDemo {
private Integer id;
private String name;
public LombokDemo() {
}
public byte byteValue() {
return this.id.byteValue();
}
public short shortValue() {
return this.id.shortValue();
}
public int intValue() {
return this.id.intValue();
}
public long longValue() {
return this.id.longValue();
}
public float floatValue() {
return this.id.floatValue();
}
public double doubleValue() {
return this.id.doubleValue();
}
public int compareTo(Integer arg0) {
return this.id.compareTo(arg0);
}
}
工具相关
@Cleanup
功能
关闭流
注意
关闭流的方式有点怪异,而且没有在finally里面关闭,如果出现异常的就不会关闭了
源码
public class LombokDemo {
public void test() throws IOException {
@Cleanup InputStream inputStream = new FileInputStream("xxx.txt");
}
}
编译后
package xyz.mrwood.study.lombok;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Collections;
public class LombokDemo {
public LombokDemo() {
}
public void test() throws IOException {
FileInputStream inputStream = new FileInputStream("xxx.txt");
if(Collections.singletonList(inputStream).get(0) != null) {
inputStream.close();
}
}
}
@Synchronized
功能
给方法加一个同步块
源码
public class LombokDemo {
@Synchronized
public void test() throws IOException {
System.out.println("test");
}
}
编译后
package xyz.mrwood.study.lombok;
import java.io.IOException;
public class LombokDemo {
private final Object $lock = new Object[0];
public LombokDemo() {
}
public void test() throws IOException {
Object var1 = this.$lock;
synchronized(this.$lock) {
System.out.println("test");
}
}
}
@SneakyThrows
功能
忽略异常
源码
public class LombokDemo {
@SneakyThrows
public void test() {
String s = new String("test".getBytes(), "utf-8");
}
}
编译后
package xyz.mrwood.study.lombok;
import java.io.IOException;
public class LombokDemo {
private final Object $lock = new Object[0];
public LombokDemo() {
}
public void test() throws IOException {
Object var1 = this.$lock;
synchronized(this.$lock) {
System.out.println("test");
}
}
}
@NonNull
功能
设置不能为空的参数
源码
public class LombokDemo {
public void test(@NonNull String val) {
}
}
编译后
package xyz.mrwood.study.lombok;
import lombok.NonNull;
public class LombokDemo {
public LombokDemo() {
}
public void test(@NonNull String val) {
if(val == null) {
throw new NullPointerException("val");
}
}
}
@UtilityClass
功能
把普通类转为工具类
源码
@UtilityClass
public class LombokDemo {
private Integer id = 1;
private String name = "kiwi";
public void util(){
System.out.println("xxx");
}
}
编译后
package xyz.mrwood.study.lombok;
public final class LombokDemo {
private static Integer id = Integer.valueOf(1);
private static String name = "kiwi";
public static void util() {
System.out.println("xxx");
}
private LombokDemo() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}