【问题标题】:Validating if multiple java object fields is not null验证多个 java 对象字段是否不为空
【发布时间】:2021-09-22 13:09:51
【问题描述】:

我想检查必填字段(姓名、年龄和邮政编码)是否包含值或不为空。

典型的方式是

        Person person = new Person();
        person.setName("Cookie");
        person.setAge(20);

//validation
    if(person.getAge() != null && person.getName() != null){
        return true;
    }

在我原来的课程中,我有 20 多个字段需要检查,因此我想知道是否有更优雅的方法来执行此操作?

简单的 POJO 类示例:

public class Person {
 
   String name;
 
   int age;
 
   String address;
 
   int postcode;
 
   public Person() {
   }
 
   public String getName() {
      return this.name;
   }
 
   public void setName(String value) {
      this.name = value;
   }
 
//...etc setter and getters
}

【问题讨论】:

  • 你应该重新设计你的类。尝试使用默认值启动每个变量,例如 int 为 0,字符串为空字符串,并且设置您的 setter 方法以检查空内容。这样一来,您就不必担心 NPE,而只需担心内容。
  • @Melron int 自动将 0 作为默认值。你也在改变功能,“”不是一个有效的名字,那为什么要验证为真呢?
  • @Stultuske 是的,我刚看到if(person.getAge() != null,我认为有一些计算并返回一个整数类?关于名称,使用if (name.equals("something")) 显然比使用if (name != null && name.equals("something")) 更好
  • 如果您不能使用验证框架(@NotNull 等),那么也许某些(如果不是全部)类和/或字段应该是不可变的,并在构造函数中进行验证.
  • 一个细节,int 不能是null,所以person.getAge() != null 永远是真的。

标签: java validation pojo


【解决方案1】:

鉴于您的所有 getter 都返回一个引用类型(无原语)并且您只需要检查结果是 null 还是不是 null,您可以试试这个:

...
private final List<Supplier<Object>> m_Getters = new ArrayList<>();
...

public Person()
{
    m_Getters.add( this::getName );
    m_Getters.add( this::getAge ); // getAge() must return Integer, not int!!!
    m_Getters.add( this::getAddress );
    ...
 }

 ...

 public final boolean validate()
 {
      return m_Getters.stream().allMatch( s -> s.get() != null );
 }

您也可以从反射调用的结果中填充列表,尽管您必须为 getter 过滤该结果。而Stream.allMatch() 的谓词会稍微复杂一些。

【讨论】:

    【解决方案2】:

    Bean 验证

    我建议使用Jakarta Bean Validation,以前称为Java Bean Validation。请参阅tutorialproject home page

    Person person = … ;
    
    Set<ConstraintViolation<Person>> violations = Validation.buildDefaultValidatorFactory().getValidator().validate(person);
    
    if (violations.isEmpty())
    {
      …
    }
    

    现在您可以为所需验证的字段添加注释(此处使用 Lombok @Data 注释以避免所有 getter 和 setter):

    @Data
    public class Person {
     
       @NotEmpty
       private String name;
     
       @Min(0)
       int age;
     
       @NotEmpty
       String address;
     
       @Min(0)
       int postcode;
     
    }
    

    顺便说一句:我认为 int 不是邮政编码的好选择,特别是对于国际使用。另外,我建议使用出生日期来代替年龄。

    【讨论】:

      【解决方案3】:

      您可以使用 javax.validation。您可以使用 NotNull 注释来注释您的对象。然后你可以用 Validator 来检查它。

      参见this 示例。

      【讨论】:

        【解决方案4】:

        您可以通过 Java-reflection API 进行检查。请参阅文档here

        即使你这次不使用它,反射式编程也是一个牢记它的好工具。

        【讨论】:

          猜你喜欢
          • 2020-10-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-29
          相关资源
          最近更新 更多