Lombok builder is missing non nullable fields
,大意是说 Lombok 构建器缺少对非空字段的处理,下面是对情况复现 demo:public class TestMain {
public static void main(String[] args) {
// Lombok builder is missing non nullable fields
Student student = Student.builder().name("xiaoming").build();
System.out.println(student.getAge());
}
}
@Builder
@Data
class Student {
@NonNull
private String name;
private int age;
}
IDE
在提示我们 age
字段不为 null
,你应该对字段进行处理初始化和赋值。IDE
层面的提示而编译器并不会实际进行检查,程序是可以正常运行的。age
为 Integer
,表示允许字段为 null
。private Integer age;
Builder.Default
设置默认值@Builder.Default
private int age = 0;
IDE
实际上是在提示我们 age
字段不为 null
,你应该对字段进行处理初始化和赋值。换句话说,你要么允许字段为 null
,要么你应该就行初始化或赋值而不是使用基本类型的默认值。null
,当然我们也可以结合 @NonNull
注解来保证字段不为 null
。 @NonNull
private Integer age;
// 编译后的 class 文件
public StudentBuilder name(@NonNull String name) {
if (name == null) {
throw new NullPointerException("name is marked non-null but is null");
} else {
this.name = name;
return this;
}
}
@Builder.Default
使用。 @Builder.Default
@NonNull
private Integer age=3;
// 编译后的 class 文件
public StudentBuilder age(@NonNull Integer age) {
if (age == null) {
throw new NullPointerException("age is marked non-null but is null");
} else {
this.age$value = age;
this.age$set = true;
return this;
}
}
public Student build() {
Integer age$value = this.age$value;
if (!this.age$set) {
age$value = Student.$default$age();
}
return new Student(this.name, age$value);
}
NullPointerException
的处理。 @Builder.Default
private int age=3;
// 编译后的 class 文件
public StudentBuilder age(int age) {
this.age$value = age;
this.age$set = true;
return this;
}
public Student build() {
int age$value = this.age$value;
if (!this.age$set) {
age$value = Student.$default$age();
}
return new Student(this.name, age$value);
}
NullPointerException
的处理null
时使用 @NonNull
和 @Builder.Default
避免此问题。null
时则需要处理 NullPointerException
问题,下面是一个建议方案:使用 Optional
进行包装,除了可以使用函数式编程的思想使代码更简洁以外,还可以让使用者明确知道该值可能为空,你需要强制进行处理,具备更好的可读性。@Builder
@Getter
class Student {
@NonNull
private String name;
private Optional<Integer> age;
}
public class TestMain {
public static void main(String[] args) {
Student.StudentBuilder builder = Student.builder().name("Ming");
builder.age(Optional.of(22));
Student student = builder.build();
System.out.println(student.getAge().orElseThrow(() -> new IllegalStateException("Age is not present")));
}
}
Optional
的组合,但在一些有性能要求的场景我们可以适当考虑方案三,减少频繁的拆箱和装箱带来的性能损耗以及减少内存占用。Optional
不是 Serializable
,作为类字段时如果需要序列化则需要进行特殊处理,比如使用 Jackson
,它会把空对象看作 null,而有值的对象则把其值看作对应域的值。? 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.
? 我对技术的热情是我不断学习和分享的动力。我的博客是一个关于Java生态系统、后端开发和最新技术趋势的地方。
? 作为一个 Java 后端技术爱好者,我不仅热衷于探索语言的新特性和技术的深度,还热衷于分享我的见解和最佳实践。我相信知识的分享和社区合作可以帮助我们共同成长。
? 在我的博客上,你将找到关于Java核心概念、JVM 底层技术、常用框架如Spring和Mybatis 、MySQL等数据库管理、RabbitMQ、Rocketmq等消息中间件、性能优化等内容的深入文章。我也将分享一些编程技巧和解决问题的方法,以帮助你更好地掌握Java编程。
? 我鼓励互动和建立社区,因此请留下你的问题、建议或主题请求,让我知道你感兴趣的内容。此外,我将分享最新的互联网和技术资讯,以确保你与技术世界的最新发展保持联系。我期待与你一起在技术之路上前进,一起探讨技术世界的无限可能性。
? 保持关注我的博客,让我们共同追求技术卓越。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。