繁体   English   中英

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

[英]Why can't I add extra argument validation in the subclass constructor?

我有两节课。 超类:

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的长度传递给超类的构造函数之前对其进行验证。 但是,我不能这样做。 我收到错误消息“构造函数调用必须是构造函数中的第一条语句”。 为什么会出现此错误? 我该如何绕过它呢?

如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;
    }
}

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

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

正如其他人所说,对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));
    }
}

超级类构造函数将始终被调用。 您可以显式调用它,也可以由Java为您执行。 而且,当您从子类构造函数中显式执行此操作时,它必须是构造函数中的第一件事。

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

公共抽象类Question(){

公共问题(字符串问题,字符串答案,字符串...替代项){...}

公共问题(字符串问题,字符串答案,字符串...替代项,布尔值checkLength){

if(checkLength && alts.length == 0){引发新的IllegalArgumentException();}

}

}

公共类StringOptionsQuestion扩展了问题{

公共StringOptionsQuestion(字符串问题,字符串答案,字符串...替代项){

super(question, answer, alts, true);

}}

暂无
暂无

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

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