繁体   English   中英

Java 构造函数绕过setter验证

[英]Java constructor bypass setter validation

在学习Java构造函数和修改器的时候,发现setter可以用来进行校验。 但是如果我们直接使用构造函数创建一个新的实例,会不会绕过setter中的验证呢? 下面是示例代码:

public static void main(String[] args){
    Person p1 = new Person("My Name", "My Gender"); //bypass setter validation
    p1.setGender("Female"); //validation is performed
}

public class Person{
    public Person(String name, String gender){
        this.name = name;
        this.gender = gender;
    }

    public void setGender(String gender){
        if(gender.equals("Male") || gender.equals("Female")){
            this.gender = gender;
        }
        else{
            this.gender = "undefined";
        }
    }
}

我看到有人提到您可以在构造函数中调用 setter,但似乎这不是一个好方法,因为很多论坛都提到它会导致一些“覆盖”问题。 如果是这种情况,我可以做些什么来确保在调用构造函数时可以执行 setter 验证?

提前致谢!

仅当 class 或 setter 为 final 时,才应在构造函数中调用 setter。 否则,子 class 可能会覆盖它,并执行其他尝试使用尚未初始化的字段的操作。

一个简单的解决方法是使字段最终。 然后您只需在构造函数中验证它,因为不需要设置器。 另一种可能性是重复验证。 但是你在复制代码,你的第一反应应该是把它重构为一个实用方法。

这可能导致这样的事情(并且我将操作数交换为equals调用为null ):

public class Person {
    public Person(String name, String gender) {
        this.name = name;
        setValidGender(gender);
    }

    public void setGender(String gender) {
        setValidGender(gender);
    }

    private void setValidGender(String gender) {
        if ("Male".equals(gender) || "Female".equals(gender)) {
            this.gender = gender;
        } else {
            this.gender = "undefined";
        }
    }
}
   public boolean validateGender(String p_gender){
    if(p_gender.equals("Male") || p_gender.equals("Female")){
       return true;
    }
    else{
       return false;
    }

那么,像上面这样的东西呢?

然后,在 setGender(String gender) 和您要在其中执行验证的构造函数中使用它?

public Person(String name, String gender){
    this.name = name;
    if(validateGender(gender)){
       this.gender = gender;
    }
    else{
       this.gender = "undefined";
    }
}

使用构建器模式并作为构建器的一部分进行验证。

所以这是交易。 在实例化 object执行字段验证是危险的,因为您想避免两件事:

  • 无效数据位于“有效” object 中(不要假设默认性别)
  • Object 是半实例化的(如果你在 object 构造过程中抛出异常,就会发生奇怪的事情

因此,请改为使用单独的 object 为您构建它,并进行适当的验证。

public PersonBuilder {
    public Person person = new Person(); // blank person object
    public static PersonBuilder getInstance() {
        return new PersonBuilder();
    }

    public PersonBuilder withName(final String name) {
        // do your validation here, and if it fails, you can blow up
        person.setName(name);
        return this;
    }

    public PersonBuilder withGender(final String gender) {
        // do your validation here, and if it fails, you can blow up
        person.setGender(gender);
        return this;
    }

    public Person build() {
        return person;
    }

}

// Usage

Person person = PersonBuilder.getInstance().withName("Tom").withGender("Male").build();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM