- @Data : 注在类上,提供类的get、set、equals、hashCode、canEqual、toString方法
- @AllArgsConstructor : 注在类上,提供类的全参构造
- @NoArgsConstructor : 注在类上,提供类的无参构造
- @Setter : 注在属性上,提供 set 方法
- @Getter : 注在属性上,提供 get 方法
- @EqualsAndHashCode : 注在类上,提供对应的 equals 和 hashCode 方法
- @Log4j/@Slf4j : 注在类上,提供对应的 Logger 对象,变量名为 log ,private static final Logger log = LoggerFactory.getLogger(UserController.class);
- @EqualsAndHashCode(callSuper = false) 作用就是自动的给model bean实现equals方法和hashcode方法,callSuper = false 表示生成的 hashcode 包括父类属性 详情参考
今天主要说下@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor
- @NoArgsConstructor
1.1 @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() {
}
}
1.2 @NoArgsConstructor 配置详解
首先来看看 @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
2.1 @RequiredArgsConstructor 实战使用
@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
就可以了。
2.2 @RequiredArgsConstructor 配置详解
先撸注解源码:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface RequiredArgsConstructor {
// 是否使用静态构造器,并制定静态构造器的名称
String staticName() default "";
// 构造器入参添加注解
AnyAnnotation[] onConstructor() default {};
@Deprecated
@Retention(RetentionPolicy.SOURCE)
@Target({})
@interface AnyAnnotation {}
}
没什么好说的,可以参见@NoArgsConstructor
- @AllArgsConstructor
3.1 @AllArgsConstructor 实战使用
@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;
}
}
3.2 @AllArgsConstructor 配置详解
@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
- Constructor 全局配置
# 如果设置为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;
}
}