Lombok(官网:https://projectlombok.org/)是一个java类库,能以简单的注解在编译源码的时候自动生成JavaBean中的log、get、set、toString、构造方法等代码,能够让JavaBean更简洁、美观,并且提高开发效率。
eclipse配置Lombok:
1.下载lombok.jar
(https://www.projectlombok.org/downloads/lombok.jar).
2.把lombok.jar
放入eclipse
的安装目录。
3.打开eclipse
安装目录下的eclipse.ini
文件在最后添加如下配置:
-Xbootclasspath/a:lombok.jar
-javaagent:lombok.jar
4.重启eclipse
生效。
然后在项目的pom.xml文件中引入maven依赖:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version><!-- 版本自己指定 -->
<scope>provided</scope><!-- 打包时不需要 -->
</dependency>
1.@Slf4j、@Log、@Log4j2、@CommonsLog、@JBossLog等
作用于类上,不同日志框架的注解,需要配合项目中使用的日志框架使用。如:
@Slf4j
public class CommonTests {
@Test
public void test1(){
log.info("=============");//可以直接使用log
}
}
2.var、val
var
可以用来表示变量的任何类型。如:
@Test
public void test1(){
var a = "abc";
log.info("{}", a instanceof String);//true
Integer b = 123;
var c = b;
log.info("{}", c instanceof Integer);//true
}
val
可以用来表示任何类型的常量。如:
@Test
public void test2(){//val
val a = "abc";//等价于:final var a = "abc";
log.info("{}", a instanceof String);//true
}
3.@Getter、@Setter
作用于属性,生成属性的get/set
方法。如:
public class User {
@Getter @Setter private Long id;//生成变量的get/set方法
@Setter private String name;//生成变量的set方法
@Getter private final Integer age = 18;//因常量值无法修改,所以不能使用@Setter
}
也可以用在类上,生成属性的get/set
方法和常量的get方法。如:
@Getter
@Setter
public class User {
private Long id;
private String name;
private final Integer age = 18;
}
4.@ToString
作用于类上,生成toString
方法,有以下可选条件:
4.1 includeFieldNames:默认值为true
,为false
时生成的toString
方法不包括属性名。如:
@ToString(includeFieldNames=false)
public class User {
private Long id = 1L;
private String name = "Lucy";
private Integer age = 18;
}
打印toString
,结果为:User(1, Lucy, 18)
。
4.2 exclude:生成toString
方法时排除某些属性。如:
@ToString(exclude={"id", "name"})
public class User {
private Long id = 1L;
private String name = "Lucy";
private Integer age = 18;
}
打印toString
,结果为:User(age=18)
。
4.3 of:生成的toString
只包含某些属性。如:
@ToString(of={"name","age"})
public class User {
private Long id = 1L;
private String name = "Lucy";
private Integer age = 18;
}
打印toString
,结果为:User(name=Lucy, age=18)
。
4.4 callSuper:默认值为false
,为true
时则生成的toString
方法里包含父类的toString
方法。
4.5 doNotUseGetters:默认值为false
,属性的get
方法存在时则使用,不存在时则直接使用属性值,为true
时指定生成toString
时不使用get
方法。
4.6 onlyExplicitlyIncluded:默认值为false
,正常情况下会包括所有的非静态(non-static
)属性,为true
时只包含使用@ToString.Include
注解标记的属性和方法。
4.7 @ToString.Exclude:在属性上使用,指定排除该属性。
4.8 @ToString.Include:在属性和方法上使用,指定包含该属性和方法。
5.@EqualsAndHashCode
作用于类上,生成equals
和hashCode
方法,和@ToString
类似有exclude、of
等可选条件。
6.NonNull
作用于属性、方法、参数、本地变量上,触发空值检查,为空时会抛出NullPointerException
。作用于属性上并配合@Setter
使用时生成代码如下:
public class User {
@NonNull
private String name;
public void setName(@NonNull String paramString) {
if (paramString == null) throw new NullPointerException("name");
this.name = paramString;
}
}
7.@AllArgsConstructor
作用于类上,生成包含所有非static、final
修饰的属性的构造方法。有以下可选条件:
7.1 staticName:私有化构造方法,并生成一个以staticName
的值命名的静态工厂函数。如:
@AllArgsConstructor(staticName="with")
public class User {
private Long id;
private String name;
private Integer age;
}
生成的代码如下:
public class User {
private Long id;
private String name;
private Integer age;
private User(Long paramLong, String paramString, Integer paramInteger) {
this.id = paramLong;
this.name = paramString;
this.age = paramInteger;
}
public static User with(Long paramLong, String paramString, Integer paramInteger) {
return new User(paramLong, paramString, paramInteger);
}
}
7.2 access:指定生成的构造方法的访问级别,默认为public
。和staticName
同时使用也可以指定静态工厂函数的访问级别。
8.@NoArgsConstructor
作用于类上,会生成没有参数的构造方法。有以下可选条件:
8.1 force:如果存在用final
修饰的成员变量且未初始化,则需使用@NoArgsConstructor(force=true)
,所有的final
属性都会被初始化为0、false、null
等。若成员变量使用了@NonNull
,那么该注解将不起作用。
8.2 staticName、access:参考上述@AllArgsConstructor
注解。
9.@RequiredArgsConstructor
作用于类上,用@NonNull
修饰的参数和用final
修饰且未初始化的参数才会加入构造方法。如:
@RequiredArgsConstructor
public class User {
private Long id;
@NonNull private String name;
private final Integer age;
}
生成的代码为:
public class User {
private Long id;
@NonNull
private String name;
private final Integer age;
public User(@NonNull String paramString, Integer paramInteger) {
if (paramString == null) throw new NullPointerException("name");
this.name = paramString;
this.age = paramInteger;
}
}
staticName、access
等可选条件参考上述@AllArgsConstructor
注解。
10.@Data
作用于类上,等价于@Getter
+@Setter
+@ToString
+@EqualsAndHashCode
+@RequiredArgsConstructor
。当有属性使用@NonNull
或者final
修饰时,生成的代码中没有公共的无参构造方法,有私有的无参构造方法,相当于上面的一串注解再加上@NoArgsConstructor(access=AccessLevel.PRIVATE)
注解。
可选条件staticConstructor
,源码注释描述为:如果指定其值,则生成的构造方法将是私有的,而创建的是可以用来创建实例的静态工厂方法。使用@Data(staticConstructor="of")
生成的静态工厂方法为:
public static User of() {
return new User();
}
其中:new User()
是私有的,在外部无法使用。
11.@Value
作用于类上,生成的代码会给所有属性加上final
修饰并生成get
方法、toString
方法和@EqualsAndHashCode
注解生成的代码。
可选条件staticConstructor
的作用与上述@Data
中staticConstructor
相同。
12.@Builder
作用于类上,生成的代码为建造者模式(Builder Pattern
),如:
User user = User.builder().id(1L).age(18).name("Lucy").build();
可以很简洁的创建对象,但此时该对象无法序列化为json
且json
也不能序列化为对象,还需要提供以下注解:
@NoArgsConstructor
+@AllArgsConstructor
+@Getter
(序列化为json
时需要)+@Setter
(反序列化为对象时需要)。
13.@Singular
作用于集合类型的属性上,配合@Builder
使用,如:
@Builder
@ToString
public class User {
private @Singular(value="books") List<String> books;
}
单元测试代码如下:
@Test
public void test(){
List<String> books1 = new ArrayList<>();
books1.add("语文");
List<String> books2 = new ArrayList<>();
books2.add("数学");
books2.add("英语");
User user = User.builder().books(books1).books(books2).clearBooks().build();
log.info("user:{}", user);
}
- 在使用
@Singular
注解的情况下输出结果为:User(books=[语文, 数学, 英语])
。并且提供了清空集合的方法:User user = User.builder().books(books1).books(books2).clearBooks().build();
- 在不使用
@Singular
注解的情况下输出结果为:User(books=[数学, 英语])。
注:
若集合属性名不是正常的英语复数则需使用@Singular("自己想要的属性名")
指定属性名。
14.@Cleanup
作用于本地变量,可以完成资源的释放。如:
try {
@Cleanup FileInputStream fis = new FileInputStream(new File("a.txt"));
@Cleanup FileOutputStream fos = new FileOutputStream("b.txt");
} catch (Exception e) {
e.printStackTrace();
}
类似于java7
以前的try-catch-finally
和java7
之后的try-with-resource
。
15.@SneakyThrows
作用于方法上,偷偷抛出Checked Exception
,而无需在方法上的throws子
句中声明需要抛出的异常。如:
@SneakyThrows
public void test(){
try {
@Cleanup FileReader fileReader = new FileReader("a.txt");
} catch (IOException e) {
e.printStackTrace();
}
}
也可以指定异常,如:@SneakyThrows(FileNotFoundException.class)
。当指定了异常之后,lombok
就会只捕捉我们指定的一种或者几种类型的异常,如果我们指定的类型没有被捕捉到,就会被抛到上一层。
16.@Delegate
能非常方便地实现代理模式。参考官网示例:https://www.projectlombok.org/features/experimental/Delegate
17.@Accessors
作用于类上,配合@Setter注解使用,可生成链式的set方法。有以下可选项:
17.1 fluent:默认为false
,为true
时生成的set
方法会return
当前对象且get/set
方法名都不再包含get/set
,如:
public String name() {//生成的get方法
return this.name;
}
public User name(String paramString) {//生成的set方法
this.name = paramString;
return this;
}
17.2 chain:默认为false
,为true
时生成的set
方法会return
当前对象且get/set
方法名为正常的get/set
方法格式,如:
public String getName() {
return this.name;
}
public User setName(String paramString) {
this.name = paramString;
return this;
}
17.3 prefix: 比如属性名是user_name
,加上注解 @Accessors(prefix = "user_")
,生成的get/set
方法中则会自动去掉“user_”
前缀。其它不是以"user_"
开头的属性则不会生成get/set
方法。
18.@Wither
作用于属性上,配合@AllArgsConstructor
注解使用,使用被修饰的属性创建一个对象,原代码为:
@AllArgsConstructor
public class User {
private Long id;
@Wither private String name;
private Integer age;
}
生成代码为:
public class User {
private Long id;
private String name;
private Integer age;
public User(Long paramLong, String paramString, Integer paramInteger) {
this.id = paramLong;
this.name = paramString;
this.age = paramInteger;
}
public User withName(String paramString) {
return this.name == paramString ? this : new User(this.id, paramString, this.age);
}
}
19.@Synchronized
作用于方法上,给方法体加锁。原代码为:
@Synchronized
public void test(){
System.out.println("test @Synchronized");
}
生成代码为:
private final Object $lock = new Object[0];
public void test() {
synchronized (this.$lock) {
System.out.println("test @Synchronized");
}
}
或者使用@Synchronized("name")
,其中name
为属性名,生成代码为:
public void test() {
synchronized (this.name) {
System.out.println("test @Synchronized");
}
}
参考网站: