跟踪空值设置为 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 字段没有设置任何值,那么它将是 nullnull 也可能是使用 setter 显式设置的,即 new Record().setValue(null).

由于将值显式设置为 null 在我的应用程序中有意义,我想跟踪空值是由用户显式设置还是只是一个隐式空值。最好的方法和正确的方法是什么?

我想出的解决方案是,

如果这是 Java脚本,它 undefined 内置于语言本身。执行此操作的最佳方法是什么 Java?

我认为考虑 null 值作为用户输入并不是最好的解决方案,因为以后您无法区分来自用户的 nullnull 字段那不是以编程方式设置的。 (即,如果您的客户需要更新记录,您将无法区分他是将值设置为 null 还是他不想更新它,因此您可以覆盖以前的值)。

所以,如果我处在你的位置,我会用一些有意义的对象值替换 null

What is the best way and the proper way to do it?

没有单一的“最佳”或“正确”方法来做到这一点,尽管尝试区分不同的原因或种类可能不是一个好主意null

以下是一些备选方案。

  1. 通过将 null 设置为非法值来避免该问题;例如

     public void setValue(Object value) { 
         if (value == null) {
             throw new NullPointerException("Value cannot be null");
         } else {
             this.value = value; 
         }
     } 
    
  2. 使用Optional<Object>.

  3. 使用Null Object Pattern.

  4. 使用零长度数组和(不可变的)空集合而不是 null 数组和集合。 (“null 表示空”优化是个坏主意。它使您的代码更复杂,更容易出现 NPE,space 的节省微乎其微。)

  5. 通过坚持将字段初始化为非空值来避免该问题。这可以使用 Builder Pattern 或使用坚持为 value 提供的值不为空的构造函数来完成。

  6. 使用一个特殊的值来表示“这个字段还没有被初始化”;例如

     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 需要在字段“未初始化”时抛出异常。
  7. 使用布尔值表示该字段尚未初始化。