使用 setter 来验证 属性 的原因是什么?

What is the reason to use setters to validate property?

我知道在 Java 中使用 setter 和 getter 的原因之一是验证 属性。但是,我想知道当我们在 class 中有一个带参数的构造函数时它是如何工作的,并且我们仍然可以使用构造函数分配错误的值。

例如:

public class Person() {
    private String firstName;
    private int age;
    
    public Person() {}

    public Person(String firstName, int age) {
        this.firstName = firstName;
        this.age = age;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age > 0 && age < 100) {
            this.age = age;
        }else{
            //throw exception
        }
    }

}

和主要 Class :

public class Main {
    public static void main(String[] args) {
        Person person1 = new Person();
        person1.setFirstName("John");
        person1.setAge(150);

        Person person2 = new Person("John", 200);
        
    }
}

在第一种情况下(person1)我们有验证,但是当使用带参数的构造函数时我们没有验证,那么我们仍然可以设置错误的年龄的优势在哪里?

您仍然可以在构造函数中调用 setter 方法并执行验证。这将防止对象以错误的年龄值实例化。这是一个例子:

class Person {
    private String firstName;
    private int age;

    public Person() {
    }

    public Person(String firstName, int age) throws Exception {
        this.firstName = firstName;
        setAge(age);
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) throws Exception {
        if (age > 0 && age < 100) {
            this.age = age;
        } else {
            throw new Exception("Age " + age + " not allowed");
        }
    }
}

public class Main {
    public static void main(String[] args) throws Exception {
        Person person2 = new Person("John", 200);
    }
}

输出为:

Exception in thread "main" java.lang.Exception: Age 200 not allowed
     at Person.setAge(Main.java:29)
     at Person.<init>(Main.java:10)
     at Main.main(Main.java:36)