Java - 如何仅创建具有有效属性的对象?

2022-09-02 19:32:21

我正在学习一门基本的Java课程,但我遇到了一个问题:只有当我将有效参数传递给构造函数时,我才如何创建对象?

在实现验证后,我是否应该创建一个备用类并从那里调用构造函数?

或者我应该/是否可以在类中使用静态方法进行验证?

在这种情况下,最佳做法是什么?


答案 1

标准做法是验证构造函数中的参数。例如:

class Range {
  private final int low, high;
  Range(int low, int high) {
    if (low > high) throw new IllegalArgumentException("low can't be greater than high");
    this.low = low;
    this.high = high;
  }
}

旁注:要验证参数是否为 null(这很常见),您可以使用:

import static java.util.Objects.requireNonNull;

Constructor(Object o) {
  this.o = requireNonNull(o); //throws a NullPointerException if 'o' is null
}

更新

回复您关于社会安全号码的具体评论。一种方法是向类中添加一个方法:

//constructor
public YourClass(String ssn) {
  if (!isValidSSN(ssn)) throw new IllegalArgumentException("not a valid SSN: " + ssn);
  this.ssn = ssn;
}

public static boolean isValidSSN(String ssn) {
  //do some validation logic
}

然后,调用代码可能如下所示:

String ssn = getSsnFromUser();
while(!YourClass.isValidSSN(ssn)) {
  showErrorMessage("Not a valid ssn: " + ssn);
  ssn = getSsnFromUser();
}
//at this point, the SSN is valid:
YourClass yc = new YourClass(ssn);

通过该设计,您实现了两件事:

  • 在使用之前验证用户输入(您应该始终这样做 - 用户非常擅长拼写错误)
  • 您已经确保如果被误用,则会引发异常,它将帮助您检测错误YourClass

您可以通过创建一个保存 SSN 并封装验证逻辑的类来更进一步。 然后接受一个对象作为参数,该参数通过构造始终是有效的SSN。SSNYourClassSSN


答案 2

我只是在构造函数本身中抛出一个非法的参数:

public class MyClass {
    private int i;

    public MyClass (int i) {
        // example validation:
        if (i < 0) {
            throw new IllegalArgumentException ("i mustn't be negatve!");
        }
        this.i = i;
}