跟踪空值设置为 Java POJO class 中字段的最佳方法
Best way to track null value set to a field in Java POJO class
我有一条记录class如下
class Record {
String name;
Object value;
public void setValue(Object value) { this.value = value; }
}
如果 value
字段没有设置任何值,那么它将是 null
。 null
也可能是使用 setter 显式设置的,即 new Record().setValue(null)
.
由于将值显式设置为 null
在我的应用程序中有意义,我想跟踪空值是由用户显式设置还是只是一个隐式空值。最好的方法和正确的方法是什么?
我想出的解决方案是,
- 布尔标志
- 使用标记 class。将值设置为
Object value = new Undefined();
并稍后执行实例检查。这里 Undefined
是一个内部虚拟 class.
- 使用
Optional<Object> value;
并将 setter 作为 public void setValue(Object value) { this.value = Optional.ofNullable(value); }
如果这是 Java脚本,它 undefined
内置于语言本身。执行此操作的最佳方法是什么 Java?
我认为考虑 null
值作为用户输入并不是最好的解决方案,因为以后您无法区分来自用户的 null
和 null
字段那不是以编程方式设置的。 (即,如果您的客户需要更新记录,您将无法区分他是将值设置为 null
还是他不想更新它,因此您可以覆盖以前的值)。
所以,如果我处在你的位置,我会用一些有意义的对象值替换 null
。
What is the best way and the proper way to do it?
没有单一的“最佳”或“正确”方法来做到这一点,尽管尝试区分不同的原因或种类可能不是一个好主意null
。
以下是一些备选方案。
通过将 null
设置为非法值来避免该问题;例如
public void setValue(Object value) {
if (value == null) {
throw new NullPointerException("Value cannot be null");
} else {
this.value = value;
}
}
使用Optional<Object>
.
-
使用零长度数组和(不可变的)空集合而不是 null
数组和集合。 (“null
表示空”优化是个坏主意。它使您的代码更复杂,更容易出现 NPE,space 的节省微乎其微。)
通过坚持将字段初始化为非空值来避免该问题。这可以使用 Builder Pattern 或使用坚持为 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;
}
}
备注:
- 这是空对象模式的变体。
- 您不需要特殊的 class 来执行此操作。
- 最好隐藏实例(或class)。因此
value
字段需要 private
并且 getter 需要在字段“未初始化”时抛出异常。
使用布尔值表示该字段尚未初始化。
我有一条记录class如下
class Record {
String name;
Object value;
public void setValue(Object value) { this.value = value; }
}
如果 value
字段没有设置任何值,那么它将是 null
。 null
也可能是使用 setter 显式设置的,即 new Record().setValue(null)
.
由于将值显式设置为 null
在我的应用程序中有意义,我想跟踪空值是由用户显式设置还是只是一个隐式空值。最好的方法和正确的方法是什么?
我想出的解决方案是,
- 布尔标志
- 使用标记 class。将值设置为
Object value = new Undefined();
并稍后执行实例检查。这里Undefined
是一个内部虚拟 class. - 使用
Optional<Object> value;
并将 setter 作为public void setValue(Object value) { this.value = Optional.ofNullable(value); }
如果这是 Java脚本,它 undefined
内置于语言本身。执行此操作的最佳方法是什么 Java?
我认为考虑 null
值作为用户输入并不是最好的解决方案,因为以后您无法区分来自用户的 null
和 null
字段那不是以编程方式设置的。 (即,如果您的客户需要更新记录,您将无法区分他是将值设置为 null
还是他不想更新它,因此您可以覆盖以前的值)。
所以,如果我处在你的位置,我会用一些有意义的对象值替换 null
。
What is the best way and the proper way to do it?
没有单一的“最佳”或“正确”方法来做到这一点,尽管尝试区分不同的原因或种类可能不是一个好主意null
。
以下是一些备选方案。
通过将
null
设置为非法值来避免该问题;例如public void setValue(Object value) { if (value == null) { throw new NullPointerException("Value cannot be null"); } else { this.value = value; } }
使用
Optional<Object>
.使用零长度数组和(不可变的)空集合而不是
null
数组和集合。 (“null
表示空”优化是个坏主意。它使您的代码更复杂,更容易出现 NPE,space 的节省微乎其微。)通过坚持将字段初始化为非空值来避免该问题。这可以使用 Builder Pattern 或使用坚持为
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; } }
备注:
- 这是空对象模式的变体。
- 您不需要特殊的 class 来执行此操作。
- 最好隐藏实例(或class)。因此
value
字段需要private
并且 getter 需要在字段“未初始化”时抛出异常。
使用布尔值表示该字段尚未初始化。