@NonNull
@NonNull 入门使用
你可以在方法或构造函数的参数上使用@NonNull让lombok为你自动生成null-check语句。
null检查会被添加到方法的最顶层,就像下面代码所示:
if (param == null) {
throw new NullPointerException("param is marked @NonNull but is null");
}
对于构造函数而言,将在任何显式this()或super()调用之后,立即插入空检查。
之前说过@Setter(如果对@Setter不了解,可以移步:)方法,并且在@Setter注解中可以使用onParam属性为生成的所有的setter方法的入参添加注解,现在我们刚好结合这两个注解进行测试。先来看看添加后的实体类:
@Getter
@Setter(
onParam_= {@NonNull}
)
@ToString
public class User {
private String username;
private String password;
}
// 编译后
import lombok.NonNull; // 导入依赖
public class User {
private String username;
private String password;
public User() { }
public String getUsername() { return this.username; }
public String getPassword() { return this.password; }
public void setUsername(@NonNull String username) {
if (username == null) {
throw new NullPointerException("username is marked @NonNull but is null");
} else {
this.username = username;
}
}
public void setPassword(@NonNull String password) {
if (password == null) {
throw new NullPointerException("password is marked @NonNull but is null");
} else {
this.password = password;
}
}
public String toString() {
return "User(username=" + this.getUsername() + ", password=" + this.getPassword() + ")";
}
}
@NonNull 全参数配置
如果lombok为你生成所有Getter,Setter,hashCode等方法以及构造函数(例如@Data),Lombok总是将字段上@NonNull的各种注释视为生成空值检查的信号。 在参数上使用lombok自己的@lombok.NonNull会导致在您自己的方法或构造函数中插入null-check语句
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
@NonNull
private String username;
@NonNull
private String password;
}
// 编译后:
import lombok.NonNull;
public class User {
@NonNull
private String username;
@NonNull
private String password;
@NonNull
public String getUsername() { return this.username; }
@NonNull
public String getPassword() { return this.password; }
public void setUsername(@NonNull String username) {
if (username == null) {
throw new NullPointerException("username is marked @NonNull but is null");
} else {
this.username = username;
}
}
// toString hashCode,以及 equals 方法省略。
public void setPassword(@NonNull String password) {
if (password == null) {
throw new NullPointerException("password is marked @NonNull but is null");
} else {
this.password = password;
}
}
public User(@NonNull String username, @NonNull String password) {
if (username == null) {
throw new NullPointerException("username is marked @NonNull but is null");
} else if (password == null) {
throw new NullPointerException("password is marked @NonNull but is null");
} else {
this.username = username;
this.password = password;
}
}
}
@Accessors
Accessors翻译是存取器。通过该注解可以控制getter和setter方法的形式。
@Accessors(fluent = true)
使用fluent属性,getter和setter方法的方法名都是属性名,且setter方法返回当前对象
@Data
@Accessors(fluent = true)
class User {
private Integer id;
private String name;
// 生成的getter和setter方法如下,方法体略
public Integer id(){}
public User id(Integer id){}
public String name(){}
public User name(String name){}
}
@Accessors(chain = true)
@Data
@Accessors(chain = true)
class User {
private Integer id;
private String name;
// 生成的setter方法如下,方法体略
public User setId(Integer id){}
public User setName(String name){}
}
@Accessors(prefix = “f”)
使用prefix属性,getter和setter方法会忽视属性名的指定前缀(遵守驼峰命名)
@Data
@Accessors(prefix = "f")
class User {
private Integer fId;
private String fName;
// 生成的getter和setter方法如下,方法体略
public Integer id(){}
public void id(Integer id){}
public String name(){}
public void name(String name){}
}
@NoArgsConstructor
@NoArgsConstructor 实战使用
@NoArgsConstructor在类上使用,它可以提供一个无参构造器,比如:
@NoArgsConstructor
public class User {
private String username;
private String password;
}
// 编译后:
public class User {
private String username;
private String password;
public User() { }
}
当然,有时候我们会使用到单例模式,这个时候我们需要将构造器私有化,那么就可以使用这样一个属性access设置构造器的权限:
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class User {
private String username;
private String password;
}
// 编译后:
public class User {
private String username;
private String password;
private User() {
}
}
当类中有final字段没有被初始化时,编译器会报错,但是也可用@NoArgsConstructor(force = true),那么Lombok就会为没有初始化的final字段设置默认值 0 / false / null, 这样编译器就不会报错,如下所示:
@NoArgsConstructor(force = true)
public class User {
private final String gender;
private String username;
private String password;
}
// 编译后:
public class User {
private final String gender = null;
private String username;
private String password;
public User() { }
}
对于具有约束的字段(例如使用了@NonNull注解的字段),不会生成字段检查,如下所示:
@NoArgsConstructor(force = true)
public class User {
private final String gender;
@NonNull
private String username;
private String password;
}
// 编译后:
public class User {
private final String gender = null;
@NonNull
private String username;
private String password;
public User() {
}
}
@RequiredArgsConstructor
@RequiredArgsConstructor 实战使用
@RequiredArgsConstructor也是在类上使用,但是这个注解可以生成带参或者不带参的构造方法。
会生成一个包含常量,和标识了NotNull的变量 的构造方法。生成的构造方法是private,如何想要对外提供使用可以使用staticName选项生成一个static方法。若带参数,只能是类中所有带有 @NonNull注解的和以final修饰的未经初始化的字段,如下所示:
@RequiredArgsConstructor
public class User {
private final String gender;
@NonNull
private String username;
private String password;
}
// 编译后:
public class User {
private final String gender;
@NonNull
private String username;
private String password;
public User(String gender, @NonNull String username) {
if (username == null) {
throw new NullPointerException("username is marked @NonNull but is null");
} else {
this.gender = gender;
this.username = username;
}
}
}
@RequiredArgsConstructor(staticName),是代表什么意思呢?
也就是说是否生成静态的构造方法,如果生成静态的构造方法,那么原来的实例构造方法将会被私有(private),然后创建一个你指定名称的静态构造方法,并且是public的。