边界检查最合适的地方-构造函数还是二传手?


问题内容

对于Java来说,它仍然相对较新,我想知道哪种更好的方法来解决这个问题。我有一个带有一些参数的类构造函数,并且在该类中还有公共获取器和设置器:

private String name;
private Float value;

public MySampleClass(String theName, Float theValue) {
    setName(theName);
    setValue(theValue);
}

public void setName(String n) {
    this.name = n;
}

public value setValue(Float v) {
    this.value = v;
}

我想对这个Float进行一些边界检查。看来放置它的最佳位置是二传手:

public value setValue(Float v) {
    if (v < 0.0f) {
        this.value = 0.0f;
    } else if (v > 1.0f) {
        this.value = 1.0f;
    }
}

这段代码最初在构造函数中以及在setter中都进行了边界检查,这似乎是多余的。我更改了构造函数以调用setter并将检查放入其中。这更有意义吗?还是我违反了一些我完全不知道的约定?


问题答案:

从构造函数中调用可重写的方法是一个坏主意。做更多这样的事情:

private String name;
private Float value;

public MySampleClass(String theName, Float theValue) {
    this.name = theName;
    setValueImpl(theValue);
}

public void setName(String n) {
    this.name = n;
}

public void setValue(Float v) {
    setValueImpl(v);
}

private void setValueImpl(Float v) {
    if (v < 0.0f) {
        this.value = 0.0f;
    } else if (v > 1.0f) {
        this.value = 1.0f;
    }
}

这样就可以在两个地方进行验证,并且消除了对可覆盖方法的调用。有关更多信息,请参见此问题。

编辑: 如果您计划子类化MySampleClass并且希望验证设置器可用,请声明它protected final而不是private