为什么我不能在子类构造函数中添加额外的参数验证?

时间:2015-05-21 13:01:58

标签: java validation constructor abstract superclass

我有两节课。超类:

public abstract class Question(){

public Question(String question, String answer, String... alts){...
}

子类:

public class StringOptionsQuestion extends Question {

public StringOptionsQuestion(String question, String answer, String... alts){
    if (alts.length == 0){throw new IllegalArgumentException();} //The compiler doesn't like this line.
    super(question, answer, alts);
}}

我希望我的子类StringOptionsQuestion在将alts传递给超类'构造函数之前验证std::chrono的长度。但是,我不能这样做。我得到错误“构造函数调用必须是构造函数中的第一个语句”。为什么会出现此错误?我怎么能绕过它?

4 个答案:

答案 0 :(得分:5)

正如kocko所说,super语句必须是构造函数中的第一个语句。但是,如果你确实真的不想在验证之前得到超级构造函数(例如因为它会破坏一个不太有用的错误),你可以在评估超级构造函数的参数时进行验证:

public class StringOptionsQuestion extends Question {

    public StringOptionsQuestion(String question, String answer, String... alts) {
        super(question, answer, validateAlternatives(alts));
    }

    private static String[] validateAlternatives(String[] alternatives) {
        if (alternatives.length == 0) { 
           throw new IllegalArgumentException();
        }
        return alternatives;
    }
}

答案 1 :(得分:3)

super()语句必须是构造函数中的第一个:

super(question, answer, alts);
if (alts.length == 0) { 
    throw new IllegalArgumentException();
}

答案 2 :(得分:1)

正如其他人所说,对super(...) 的调用必须是子类构造函数中的第一个语句。

但是,它不一定是第一个被评估的表达式

如果真的需要在调用超类构造函数之前做一些事情(这不是标准代码 - 你应该记录为什么你这样做,如果你这样做)那么你可以做类似的事情这,通过调用静态方法作为表达式:

public class StringOptionsQuestion extends Question {

    private static String[] checkAlts(String[] alts) {
        if (alts.length == 0) {
            throw new IllegalArgumentException();
        }
        return alts;
    }

    public StringOptionsQuestion(String question, String answer, String... alts) {
        super(question, answer, checkAlts(alts));
    }
}

答案 3 :(得分:0)

将始终调用超类构造函数。你明确地调用它或java为你做。当你从子类构造函数中明确地执行它时,它必须是构造函数中的第一件事。

我不确定你的要求究竟是什么,但我想你是想避免在你的StringOptionsQuestion子类的情况下构建对象,如果alts.length == 0.你可以通过在你的超​​级中添加另一个构造函数来实现采用额外布尔参数的类说' checkLength'如果其值为true则验证长度并在需要时抛出异常。然后从StringOptionsQuestion子类中调用新的构造函数。

公共抽象类问题(){

public Question(String question,String answer,String ... alts){... }

public Question(String question,String answer,String ... alts,boolean checkLength){

if(checkLength&& alts.length == 0){throw new IllegalArgumentException();}

}

}

public class StringOptionsQuestion扩展问题{

public StringOptionsQuestion(String question,String answer,String ... alts){

super(question, answer, alts, true);

}}