Lombok踩坑
@Data注解
Lombok的toString方法在展示数据时默认调用的是Get方法,如果有逻辑需要在Get取值时进行计算,并且此值在创建对象以后为null值就会出现问题。
例如,下面的实体类使用toString方法时,默认使用getAge方法,如果age字段为null,则会发生空指针异常
@Data
public class TestDomain {
private Integer age;
public Integer getAge(){
return age.intValue();
}
}
需要增加注解@ToString(doNotUseGetters=false),会直接取实体中属性的值。
@ToString(doNotUseGetters=false) 是默认调用Get取值的意思。
@Builder注解
@Data和@Builder注解导致无参构造器消失
使用@builder注解时
@Data
@Builder
public class TestDomain {
private Integer age;
private String name;
}
如果使用无参构造器new TestDomain()
初始化对象,编译器会提示:
'TestDomain(java.lang.Integer, java.lang.String)' 在 'com.domain.TestDomain' 中不为 public。无法从外部软件包访问
在编译时,会报错:
java: 无法将类 com.domain.TestDomain中的构造器 TestDomain应用到给定类型;
需要: java.lang.Integer,java.lang.String
找到: 没有参数
原因: 实际参数列表和形式参数列表长度不同
因为只加@build注解只会生成访问权限是default的全参数构造器,无法从外部程序包中对其进行创建。
单独使用@Data注解,会生成无参数的构造方法,Java的特性
public TestDomain() {
}
单独使用@Builder注解,会生成全属性的构造方法
TestDomain(final Integer age, final String name) {
this.age = age;
this.name = name;
}
两个注解一起使用,没有了无参构造方法,只有全属性构造方法
TestDomain(final Integer age, final String name) {
this.age = age;
this.name = name;
}
此时手动添加无参数构造方法或者用@NoArgsConstructor注解都会报错,如下,因为此时只有无参构造器,没有全参数构造器(也可以在自己实现的无参数构造方法上面新增@Tolerate
注解)
java: 无法将类 com.domain.TestDomain中的构造器 TestDomain应用到给定类型;
需要: 没有参数
找到: java.lang.Integer,java.lang.String
原因: 实际参数列表和形式参数列表长度不同
解决方式就是特别声明需要同时添加无参构造器和全参数构造器,可以在domain类里手动实现构造器,或者增加注解@NoArgsConstructor @AllArgsConstructor
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TestDomain {
private Integer age;
private String name;
}
@Builder注解使默认值失效
如果domain对象字段有初始值,使用.builder().build()方法构造对象会使默认值失效
总结
想要使用@Builder,最简单的方法就是直接写上这4个注解,有默认值的话再加上@Builder.Default注解
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TestLombok {
@Builder.Default
private String aa = "zzzz";
public static void main(String[] args) {
TestLombok build = TestLombok.builder().build();
System.out.println(build);
}
}