Constructors made to order: Generates constructors that take no arguments, one argument per final / non-null field, or one argument for every field.
@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() {
}
}
首先来看看
@NoArgsConstructor
注解源码部分的实现:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface NoArgsConstructor {
String staticName() default "";
// 在构造方法的入参上添加注解。e.g. @NonNull
// up to JDK7: @EqualsAndHashCode(onParam=@__({@AnnotationsGoHere}))
// from JDK8: @EqualsAndHashCode(onParam_={@AnnotationsGohere})
AnyAnnotation[] onConstructor() default {};
// 设置构造方法的访问权限,默认是 public
AccessLevel access() default lombok.AccessLevel.PUBLIC;
// 是否强制对未赋值的final字段初始化值。
boolean force() default false;
@Deprecated
@Retention(RetentionPolicy.SOURCE)
@Target({})
@interface AnyAnnotation {}
}
看到有这样一个注解属性:
staticName
,是代表什么意思呢?也就是说是否生成静态的构造方法,如果生成静态的构造方法,那么原来的实例构造方法将会被私有(
private
),然后创建一个你指定名称的静态构造方法,并且是public
的,如下所示:
@NoArgsConstructor(staticName = "UserHa")
public class User {
private String username;
private String password;
}
// 编译后:
public class User {
private String username;
private String password;
private User() { }
public static User UserHa() {
return new User();
}
}
@RequiredArgsConstructor
也是在类上使用,但是这个注解可以生成带参或者不带参的构造方法。
若带参数,只能是类中所有带有 @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;
}
}
}
如果针对User类使用@RequiredArgsConstructor
注解实现空参构造方法,那么我们就要这样定义实体类:
@RequiredArgsConstructor
public class User {
private final String gender = "男";
private String username;
private String password;
}
当然如果我们要是想生成空参构造,仅适用上一个注解@NoArgsConstructor
就可以了。
先撸注解源码:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface RequiredArgsConstructor {
// 是否使用静态构造器,并制定静态构造器的名称
String staticName() default "";
// 构造器入参添加注解
AnyAnnotation[] onConstructor() default {};
@Deprecated
@Retention(RetentionPolicy.SOURCE)
@Target({})
@interface AnyAnnotation {}
}
没什么好说的,可以参见
@NoArgsConstructor
@AllArgsConstructor
同样是在类上使用,该注解提供一个全参数的构造方法,默认不提供无参构造。
需要注意的是,这里的全参不包括已初始化的final字段(主要是final
字段,一旦被赋值不允许再被修改)。
@AllArgsConstructor
public class User {
private final String gender;
private String username;
private String password;
}
// 编译后
public class User {
private final String gender;
private String username;
private String password;
public User(String gender, String username, String password) {
this.gender = gender;
this.username = username;
this.password = password;
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface AllArgsConstructor {
// 是否使用静态构造器,并制定静态构造器的名称
String staticName() default "";
// 构造器入参添加注解
AnyAnnotation[] onConstructor() default {};
// 设置构造器的访问权限
AccessLevel access() default lombok.AccessLevel.PUBLIC;
@Deprecated
@Retention(RetentionPolicy.SOURCE)
@Target({})
@interface AnyAnnotation {}
}
同样这几个属性配置方式,也可以参见
@NoArgsConstructor
# 如果设置为true,则lombok将向生成的构造函数添加 @java.beans.ConstructorProperties。
lombok.anyConstructor.addConstructorProperties = [true | false] (default: false)
# 是否禁用这几种构造器注解
lombok.[allArgsConstructor|requiredArgsConstructor|noArgsConstructor].flagUsage = [warning | error] (default: not set)
lombok.anyConstructor.flagUsage = [warning | error] (default: not set)
# 是否支持复制现有的注解,在本类中使用。e.g. @Nullable/@NonNull annotations
lombok.copyableAnnotations = [A list of fully qualified types] (default: empty list)
测试 addConstructorProperties
全局配置文件内容
config.stopBubbling = true
# 首先清除原有配置
clear lombok.anyConstructor.addConstructorProperties
# 设置新的配置
lombok.anyConstructor.addConstructorProperties = true
实体类
@AllArgsConstructor
public class User {
private String username;
private String password;
}
// 编译后:
public class User {
private String username;
private String password;
@ConstructorProperties({"username", "password"}) // 被添加
public User(String username, String password) {
this.username = username;
this.password = password;
}
}
值得注意一点的是:
@ConstructorProperties
只能用在JDK 6
中
.
.
.
.
.
.