【发布时间】:2016-04-08 09:39:46
【问题描述】:
假设我有一个带有Collection 字段的 POJO/Java Bean 类:
public class Foo{//original code
private List<Bar> barList;
public List<Bar> getBarList(){
return this.barList;
}
public void setBarList(List<Bar> barList){
this.barList=barList;
}
}
getBarList() 被调用时如何避免 NPE?我的意思是getBarList() 可能会返回 null 并且调用者会抛出 NPE。假设我必须保持 setter 和 NULL 在这里没有语义。
public class Foo{//modified code.
private List<Bar> barList = new ArrayList<Bar>();//1) default value since construct to avoid this.barList being null.
public List<Bar> getBarList(){
return this.barList;
}
public void setBarList(List<Bar> barList){
//2.a) check and throw a NPE
Objects.requireNonNull(barList);
//2.b) replace the NULL value
if(barList==null){
this.barList.clear();//less cost then `this.barList = new ArrayList<Bar>();`
}else{
this.barList=barList;
}
}
}
- 每个收集字段是否需要 1)?
- 哪个更好,2.a) 还是 2.b)?为什么? Guava 选择了 2.a),例如
FluentIterable.from(null),但它不是 POJO/Java Bean。 - POJO/Java Bean 是否有任何最佳实践或原则可以遵循以避免 NPE?我认为修改后的代码不再是 setter 中某些逻辑代码的 POJO。
谢谢!
【问题讨论】:
-
2 和 3 解决不了任何问题,因为您不能确定在调用 getter 之前调用了 setter
-
@Anderson 我删除了我的评论,但你的说法是错误的。
this.barList与barList是不同的变量,并导致 setter 方法的行为不同。 -
getBarList()可能会返回 null,但绝不会抛出 NPE! -
@Anderson 删除断言,默认情况下它们在 Java 中未启用。如果您真的想避免所有麻烦:在 foo 实例化时实例化 List,并且不允许 setter 设置 null 值。
-
我不会将以上所有内容视为一种模式。有许多因素使该设计合理或无用。没有一种单一的“万能”解决方案可以避免客户端出现 NPE。大多数情况下,您没有幸运地从头开始创建设计,并且可以首先应用模式。大多数情况下,你必须“用你得到的东西工作”。其中可以包括“不能返回不可变列表”或“客户端依赖 NULL 来获取语义”...
标签: java nullpointerexception javabeans pojo