引言
开发中经常要创建一些实体类并要添加getter/setter方法、构造方法、toString方法等重复性工作,虽然IDEA有快捷键ALT+INSERT
快速实现,但我们想通过某种方式可以自动生成。这个时候就需要用到本篇的主角——Lombok。
简介
Lombok是一款Java开发插件,可以通过它定义的注解来精简代码,主要针对简单的Java模型对象(Plain Ordinary Java Object,即POJO)。特别是当POJO类的属性增减时,这个时候如果使用注解,则不需要额外的操作,否则的话还得重新构建。而且Lombok针对这些内容的处理是在编译期,而不是通过反射机制。
安装
本篇是基于IDEA介绍。在IDEA中打开Settings—>Plugins,搜索Lombok,如下图所示,点击安装,然后重启IDEA。
插件安装完成后在使用时需要在pom.xml中配置:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
使用说明
1. 作用在类上
1.1. @Data
@Data最常用的注解之一。作用在类上,提供该类所有属性的get/set方法,还提供了equals、canEqual、hashCode、toString方法。并且默认是无参构造方法。
程序清单1:@Data注解
/**
* @author Carson Chu, 1965704869@qq.com
* @date 2020/2/3 20:00
* @description
*/
@Data
public class UserInfoModel {
private String username;
private String password;
private Integer age;
public static void main(String[] args) {
UserInfoModel userInfoModel = new UserInfoModel();
userInfoModel.setUsername("Carson");
/* carson==>UserInfoModel(username=Carson, password=null, age=null) */
System.out.println(userInfoModel.getUsername() + "==>" + userInfoModel.toString());
}
}
1.2. @Value
作用于类上,会生成含所有参数的构造方法、get方法、equals、hashCode、toString方法。与@Data相比,多了全参构造方法,少了默认构造方法、set方法和canEqual方法。
需要注意的是:该注解会将字段添加上final修饰,个人感觉没有太大必要,开发中尽量少使用。
程序清单2:@Value注解
/**
* @author Carson Chu, 1965704869@qq.com
* @date 2020/2/3 20:00
* @description
*/
@Value
public class UserInfoModel {
private String username;
private String password;
private Integer age;
public static void main(String[] args) {
UserInfoModel userInfoModel = new UserInfoModel("Carson","2020",18);
/* Carson==>UserInfoModel(username=Carson, password=2020, age=18) */
System.out.println(userInfoModel.getUsername() + "==>" + userInfoModel.toString());
}
}
1.3. @Setter和@Getter
@Setter和@Getter用法相同,都可以作用在类上和变量上,当作用在类上,就是对类中所有属性生成set或者get方法,当作用在变量上,则是对特定的变量生成set或者get方法。
程序清单3:@Setter和@Getter注解
@Setter
public class UserInfoModel {
private String username;
private String password;
@Getter
private Integer age;
}
1.4. @Log4j
作用于类上,为该类提供一个参数名为log的Log4j的日志对象。
程序清单4:@Log4j注解
@Log4j
public class UserInfoModel {
public static void main(String[] args) {
log.info("@Log4j");
}
}
1.5. @AllArgsConstructor和@NoArgsConstructor
两个注解都作用于类上,@AllArgsConstructor为该类提供一个包含所有参数的构造方法。@NoArgsConstructor提供一个无参的构造方法,它可以和@AllArgsConstructor同时使用,此时会生成两个构造方法:无参构造方法和全参构造方法。
程序清单5:@AllArgsConstructor和@NoArgsConstructor注解
@AllArgsConstructor
@NoArgsConstructor
public class UserInfoModel {
private String username;
private String password;
public static void main(String[] args) {
UserInfoModel userInfoModel=new UserInfoModel();
UserInfoModel userInfoModel1=new UserInfoModel("Carson","2020");
}
}
1.6. @RequiredArgsConstructor
作用于类上,由类中所有带有@NonNull注解(接下来会说明)或者带有final修饰的成员变量作为参数生成构造方法。
程序清单6:@RequiredArgsConstructor注解
@RequiredArgsConstructor
public class UserInfoModel {
private final String username;
private String password;
@NonNull
private Integer age;
public static void main(String[] args) {
UserInfoModel userInfoModel = new UserInfoModel("Carson", 18);
}
}
1.7. @Builder
作用于类上,支持Builder的流式操作。
1.8. @ToString
作用于类上,生成包含所有参数的toString方法。
2. 作用在变量上
2.1 @NonNull
作用于变量上,提供关于此参数的非空检查,如果参数为空,则抛出空指针异常。如下图所示,我们已经知道@Data会默认生成无参构造方法,但是当类中有参数被@NonNull修饰之后,无参构造方法将会失效,取而代之的是由所有@NonNull注解的变量组成的有参构造方法。
3. 作用在方法上
3.1 @Synchronized
作用于类方法或实例方法上,效果与synchronized相同。区别如下表所示:
加锁方式 | 作用域 | 加锁对象 |
---|---|---|
synchronized | 类方法 | 类的Class对象 |
synchronized | 实例方法 | this对象 |
@Synchronized | 类方法 | private static final对象 |
@Synchronized | 实例方法 | private final对象 |
当注解@Synchronized作用在非静态方法时,需要在注解中指向一个自定义的private final锁对象。
程序清单7:@Synchronized注解
public class UserInfoModel {
private final Object LOCK = new Object();
private static Integer staticCounter;
@Synchronized
public static int incr() {
return ++staticCounter;
}
@Synchronized("LOCK")
public int decr() {
return --staticCounter;
}
}
该类编译之后的class文件为:
public class UserInfoModel {
private static final Object $LOCK = new Object[0];
private final Object LOCK = new Object();
private static Integer staticCounter;
public UserInfoModel() {
}
public static int incr() {
synchronized($LOCK) {
return staticCounter = staticCounter + 1;
}
}
public int decr() {
synchronized(this.LOCK) {
return staticCounter = staticCounter - 1;
}
}
}
可以看到,程序为@Synchronized注解作用的静态方法自动创建了一个private static final类型的锁对象private static final Object $LOCK = new Object[0];
。
3.1 @SneakyThrows
作用于方法上,相当于把方法内的代码添加了一个try-catch处理。
小结
在本篇末对Lombok做个小结,说一下个人的看法,此神器虽然好用,但是在代码的可读性方面却是不如手动生成的get/set、toString方法。开发工具虽然带来了极大的便利,但软件开发人员还是不应该过于依赖工具。该需要亲自动手去实现的还是踏实一点,千里之行,始于足下。