我有一个记录类,如下所示
class Record {
String name;
Object value;
public void setValue(Object value) { this.value = value; }
}
如果没有为value
字段设置值,则它将是null
。 也可能是使用setter(即newrecord().setValue(null)
显式设置了null
。
由于显式地将值设置为null
在我的应用程序中具有意义,所以我想跟踪null值是由用户显式设置的还是只是一个隐式null。 什么是最好的方式,什么是正确的方式去做?
我想出的解决办法是,
object value=new Undefined();
,稍后执行实例检查。 这里的未定义
是一个内部虚拟类。选项
,并将setter设置为public void setValue(对象值){this.value=optional.ofnullable(值);}
如果这是JavaScript,则在语言本身中内置了undefined
。 做这个Java最好的方法是什么?
我认为将null
值视为用户条目并不是最好的解决方案,因为以后,您无法将来自用户的null
字段与不是以编程方式设置的null
字段区分开来。 (即,如果您的客户端需要更新记录,您将无法区分他是将值设置为null
,还是他不想更新它,因此您可以覆盖以前的值)。
因此,如果我在您的位置,我将用一些有意义的对象值替换null
。
什么是最好的方式,什么是正确的方式去做?
没有单一的“最佳”或“适当”方法来做到这一点,尽管试图区分不同的原因或null
种类可能是个坏主意。
下面是一些可供选择的方法。
>
通过使null
成为非法值来避免此问题; 例如。
public void setValue(Object value) {
if (value == null) {
throw new NullPointerException("Value cannot be null");
} else {
this.value = value;
}
}
使用选项
。
使用空对象模式。
使用零长度数组和(不可变的)空集合,而不是null
数组和集合。 (null
表示空优化会使代码更加复杂。)
通过坚持将字段初始化为非NULL值来避免该问题。 这可以使用构建器模式来完成,或者使用一个构造函数来坚持为value
提供的值不为空。
使用特殊值表示“此字段尚未初始化”; 例如。
private static final Object UNINITIALIZED = new Object();
private Object value = UNINITIALIZED;
public void getValue() {
if (value == UNINITIALIZED) {
throw new UninitializedFieldException("Value is uninitialized");
} else {
return value;
}
}
注意事项:
value
字段需要是private
,如果字段是“uninitialized使用布尔值表示字段尚未初始化。