跟踪Java POJO类中字段的空值集的最佳方法

跟踪Java POJO类中字段的空值集的最佳方法,java,null,setter,Java,Null,Setter,我有一个记录类如下 class Record { String name; Object value; public void setValue(Object value) { this.value = value; } } 如果值字段未设置任何值,则它将为null。也可能是使用setter显式设置了null,即newrecord()。setValue(null) 因为显式地将值设置为null在我的应用程序中有意义,所以我想跟踪null值是由用户显式地设置的还是只是一个隐式的nul

我有一个记录类如下

class Record {
  String name;
  Object value;
  public void setValue(Object value) { this.value = value; }
}
如果
字段未设置任何值,则它将为
null
。也可能是使用setter显式设置了
null
,即
newrecord()。setValue(null)

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

我想出的解决办法是

  • 布尔标志
  • 使用标记类。将值设置为
    对象值=新的未定义()并稍后执行实例检查。这里
    Undefined
    是一个内部伪类
  • 使用
    可选值
    并将setter设置为
    public void setValue(Object value){this.value=Optional.ofNullable(value);}

如果这是JavaScript,那么它在语言本身中构建了
未定义的
。执行Java的最佳方法是什么?

我认为将
null
值视为用户条目并不是最好的解决方案,因为稍后,您无法区分来自用户的
null
和非编程设置的
null
字段。(即,如果您的客户需要更新记录,您将无法区分他是将值设置为
null
还是不想更新,因此您可以覆盖以前的值)


因此,如果我在你的位置上,我会用一些有意义的对象值替换
null

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

因此,如果我处在您的位置,我会用一些有意义的对象值替换
null

什么是最好的方法和正确的方法

没有单一的“最佳”或“适当”方法可以做到这一点,尽管尝试区分不同的原因或类型的
null
,可能是一个坏主意

以下是一些备选方案

  • 通过将
    null
    设置为非法值来避免问题;e、 g

     public void setValue(Object value) { 
         if (value == null) {
             throw new NullPointerException("Value cannot be null");
         } else {
             this.value = value; 
         }
     } 
    
  • 使用
    可选

  • 使用

  • 使用零长度数组和(不可变)空集合,而不是
    null
    数组和集合。(优化“
    null
    意味着空”是个坏主意。它会使代码更复杂,更容易出现NPE,节省空间也很小。)

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

  • 使用特殊值表示“此字段尚未初始化”;e、 g

    注:

    • 这是空对象模式的变体
    • 你不需要一个特殊的类来做这件事
    • 最好将实例(或类)隐藏起来。因此,
      value
      字段需要是
      private
      ,如果字段“未初始化”,则getter需要抛出异常
  • 使用布尔值表示字段尚未初始化

  • 什么是最好的方法和正确的方法

    没有单一的“最佳”或“适当”方法可以做到这一点,尽管尝试区分不同的原因或类型的
    null
    ,可能是一个坏主意

    以下是一些备选方案

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

     public void setValue(Object value) { 
         if (value == null) {
             throw new NullPointerException("Value cannot be null");
         } else {
             this.value = value; 
         }
     } 
    
  • 使用
    可选

  • 使用

  • 使用零长度数组和(不可变)空集合,而不是
    null
    数组和集合。“
    null
    意味着空”优化是一个坏主意。它使代码更复杂,更容易NPE,节省的空间也很小。)

  • 通过坚持将字段初始化为非空值来避免此问题。这可以通过使用或使用构造函数来实现,该构造函数坚持为
    提供的值不为空

  • 使用特殊值表示“此字段尚未初始化”;例如

    注:

    • 这是空对象模式的变体
    • 你不需要一个特殊的类来做这件事
    • 最好将实例(或类)隐藏起来。因此,
      value
      字段需要是
      private
      ,如果字段“未初始化”,getter需要抛出异常
  • 使用布尔值表示字段尚未初始化


  • 第三个似乎是最好的。为什么值是对象和特定类型?您可以尝试探索该选项,然后选择第三个选项。不确定这是否是最好的方法,但在阅读代码时看起来非常优雅。只是一个建议:只要可能,不要允许未初始化的字段。在您的示例中,我将创建构造函数
    记录(对象值){this.value=value;}
    ,它要求在创建对象时初始化字段。如果必须设置值(强制),则可以使用生成器强制提供值。在这种情况下,你可以摆脱对未设置字段的担忧。第三个字段似乎是最好的。为什么值是对象和特定类型?您可以尝试探索该选项,然后选择第三个选项。不确定这是否是最好的方法,但在阅读代码时看起来非常优雅。只是一个建议:只要可能,不要允许未初始化的字段。我