Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在构造函数中使用set方法初始化类';s场?_Java_Constructor_Mutators - Fatal编程技术网

Java 在构造函数中使用set方法初始化类';s场?

Java 在构造函数中使用set方法初始化类';s场?,java,constructor,mutators,Java,Constructor,Mutators,我想在构造函数中使用类的set方法来检查要初始化的值,如果它们不符合我设置的约束,就会抛出异常 代码示例: public class MyClass { // Fields private int number; private String string; // Constructor public MyClass(int number, String string) { setNumber(number); setS

我想在构造函数中使用类的set方法来检查要初始化的值,如果它们不符合我设置的约束,就会抛出异常

代码示例

public class MyClass {

    // Fields
    private int number;
    private String string;

    // Constructor
    public MyClass(int number, String string) {
        setNumber(number);
        setString(string);
    }

    // Set Methods
    public void setNumber(int number) {
        if (number<=0) {    // Certain constrain for number
            throw new IllegalArgumentException("Number must be positive");
        }
        this.number = number;
    }

    public void setString(String string) { // Certain constrain for string
        if (string.equals("")) {
            throw new IllegalArgumentException("string cannot be empty");
        } 
        this.string = string;
    }

    public String toString() {
        return String.format("Ordered %d x %s%n", number, string);
    }

    public static void main(String[] args) {
        MyClass obj = new MyClass(8, "Souvlaki");   // Everything allright
        System.out.println(obj);
        try {
            MyClass obj2 = new MyClass(-3, "Mousaka");  // Error in number argument
        } catch (IllegalArgumentException exception) {  // catch the exception
            System.out.printf("Exception Caught: Number must be positive%n%n");
        }
        MyClass obj2 = new MyClass(4, "");  // Error in string argument
        // Allow the exception to end program execution
    }
}
公共类MyClass{
//田地
私有整数;
私有字符串;
//建造师
公共MyClass(整数、字符串){
setNumber(数字);
设置字符串(字符串);
}
//设置方法
公共无效集合号(整数){

if(number而不是在构造函数中进行验证,您可以在类中创建一个
checkInvariant()
方法,该方法验证所有字段

class MyClass {
    private int num;
    private String value;

    public void checkInvariants() {
        assertNotEmpty(value, "String value cannot be empty");
        assertPositive(num, "Number num should be non-negative");
    }
}
然后在其他地方,您可以将该类的实例作为参数传递,首先调用此方法以确保不变量保持不变:

class SomeOtherClass {
    public void doSomethingWithMyClass(MyClass myClass) {
        myClass.checkInvariants();
        // Proceed with work.
    }
}

变量可以在类中的任何位置访问,因此无需使用mutator方法初始化变量

如果要对输入参数进行一些验证,请使用另一种方法执行所有必需的验证


调用构造函数中的验证方法。

正如注释所示,这可能有问题。特别是,您可能想看一看。底线大致是:有人可能以意外的方式重写
集…
方法,并引用其他(未初始化的)方法类的字段,这可能导致各种错误

专用的验证方法可能是一种选择。但这些方法可能会被调用多次,即使在不需要验证的情况下也是如此

您可以通过将
设置为…
方法
final
来缓解大多数问题。无论如何,这是一个很好的实践。正如Joshua Bloch在其《有效Java》一书第17项中所说:

“为继承而设计和编写文档,否则禁止继承”


这意味着您应该将每个方法设置为final,除非您明确希望允许重写它,并记录应该如何重写它(或者,将整个类设置为final)。

if(string==“”)
不要再这样做了……请避免这样做。是和否。如果您正在使用的方法假设某种状态,而这种状态在类构造之后才能得到保证,则可能会出现问题。就我个人而言,我倾向于这样做,以确保继承可以工作,允许子类根据需要重写集合方法,而不需要这样做求助于讨厌的黑客来让它工作,但那是我…@RohitJain:如果所有的二传手都是最终的(或者如果课程本身是最终的),这个问题消失了。你可能想用builders代替header。如果我这样做的话,它需要调用两次这个方法。一次调用setter,一次调用构造函数。除了向类中添加一个方法外,这个方法仍然需要是final的,正如@Marco13在他的回答中提到的那样,以防止像const中那样的意外错误structor.Yes.AKA“让
这个
从构造函数中逃逸”