文章目录
一、Lombok是什么
自从Java 6起,javac就支持“JSR 269 Pluggable Annotation Processing API”规范,只要程序实现了该API,就能在javac运行的时候得到调用。
Lombok就是一个实现了"JSR 269 API"的程序。在使用javac的过程中,它产生作用的具体流程如下:
-
javac对源代码进行分析,生成一棵抽象语法树(AST)
-
javac编译过程中调用实现了JSR 269的Lombok程序
-
此时Lombok就对第一步骤得到的AST进行处理,找到Lombok注解所在类对应的语法树 (AST),然后修改该语法树(AST),增加Lombok注解定义的相应树节点
-
javac使用修改后的抽象语法树(AST)生成字节码文件
二、使用Lombok
1、引入依赖
Lombok的scope=provided,说明它只在编译阶段生效,不需要打入包中。事实正是如此,Lombok在编译期将带Lombok注解的Java文件正确编译为完整的Class文件。
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
2、IDEA安装Lombok插件
IDEA: File->Settings->Plugins, Marketplace中搜索Lombok安装。
在IDEA中启用Lombok,开启该项是为了让Lombok注解在编译阶段起到作用。
三、注解使用
3.1 基础注解
@Getter和@Setter
作用类上生成所有成员变量的getter/setter方法;作用于成员变量上生成该成员变量的getter/setter方法。
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
会自动生成下面这些方法。
@ToString
作用于类,覆盖默认的toString()方法,可以通过of属性限定显示某些字段,通过exclude属性排除某些字段。
@ToString(exclude={“column1”,“column2”}):排除多个column列所对应的元素
@ToString(of={“column1”,“column2”}):只生成包含多个column列所对应的元素
@EqualsAndHashCode
作用于类,注解会自动重写对应的equals方法和hashCode方法。 如果某些变量不想要加进判断,可以透过 exclude 排除,也可以使用 of 指定某些字段。
Q : 为什么只有一个整体的 @EqualsAndHashCode
注解,而不是分开的两个 @Equals
和 @HashCode
?
A : 在 Java 中有规定,当两个对象 equals 时,他们的 hashcode 一定要相同,反之,当 hashcode 相同时,对象不一定 equals。所以 equals 和 hashcode 要一起实现,免得发生违反 Java 规定的情形发生
@Data
在类中使用,自动为所有字段添加@Getter @Setter @ToString @EqualsAndHashCode @RequiredArgsConstructor注解 。
import lombok.Data;
@Data
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
会自动生成下面这些方法。
@Value
注解和@Data类似,区别在于它会把所有成员变量默认定义为private final修饰,并且不会生成setter方法,适合加在值不希望被改变的类上。
@NonNull
主要作用于成员变量和参数中,标识赋值时进行判空检查,为空抛出空指针异常java.lang.NullPointerException。
@Accessors(chain = true)
用来给类中set方法开启链式调用。chain属性:用来指定是否开启ser方法的链式调用。
@Cleanup
自动调用close()方法,如果有使用流之类的可以使用,确保已分配的资源被释放。
@Synchronized
@Sychronized 是一个处理线程安全问题的annotation,使用方法和关键字 synchronized比较类似,但是有一些不同点就是,关键字synchronized是锁定当前对象(this指针), 而@Synchronized则会锁定一个private的常量。如果当前类中没有这个常量,就会自动生成一个。是直接锁方法,而是锁代码块。
import lombok.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");
}
}
编译后如下所示,当前锁定的方法是一个静态的方法的话,会自动生成一个静态常量,如果是一个普通方法的话会生成一个普通常量,类型为Object。
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");
}
}
}
3.2 构造器注解
作用于类上,用于生成构造函数。有staticName、access等属性。
staticName属性一旦设定,将生成指定名称的static方法,access属性可以限定访问权限。
@NoArgsConstructor和@AllArgsConstructor
在类中使用,注解会生成无参构造器和全部参数的构造器。两个参数一般是一起使用的。
@RequiredArgsConstructor
生成一个仅包含final和@NonNull注解修饰的成员变量的构造器。如果所有的变量都是正常的,都没有用 final 或者修饰@NonNull的话,那就会生成一个没有参数的构造器。
3.3 日志注解
用于快速给类中定义一个日志变量log,最常用的就是 @Slf4j。
@Log @Log4j @Log4j2 @Slf4j @XSlf4j
在类上加下面这些注解,就不再需要下面这些声明语句。
//@Log
private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
//@Log4j
private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);
//@Log4j2
private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);
//@Slf4j
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
//@XSlf4j
private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);
举例,可以用[{}]
进行占位,转换变量。