抓住断言错误的Java

时间:2016-05-06 21:47:08

标签: java try-catch assert

我自己练习了一些Java SE 7并遇到了以下问题。我编写了一个公共静态void函数 ValidDate ,它接受三个字符串,如果日期无效,则只抛出一个断言错误。 ValidDate 使用两个字符串数组( MONTHS DAYS )作为库来验证给定日期。 ValidDate 在每个断言测试结束时也有一个唯一的断言表达式:

public static void ValidDate(String month, String day, String year){
    boolean validday = false;
    boolean validmonth = false;
    boolean validyear = true;

    try{
        Integer.parseInt(year);
    }catch(NumberFormatException e){
        validyear = false;
    }
    assert(validyear): "Error: year entry not written in integers.";


    for(String m:MONTHS){
        if(m.equals(month)){
            validmonth = true;
        }
    }
    assert (validmonth): "Error: month entry is not valid; must be an"
            + " integer between (0)1 and 12.";

    ...
}

我的目的是为我的公共类 Person <添加 ValidDate 作为 DOB setter( SetDOB )的帮助功能/ em>的。当在setter中输入无效的 DOB 时,实现将使 ValidDate 抛出异常,然后 SetDOB 将输出一条消息输入 DOB 是不可接受的,不会更改当前的 DOB 值:

public void SetDOB(String newDOB){
    String[] dates = newDOB.split("/");
    boolean validdate = true;
    if(dates.length == 3){
        try{
            ValidDate(dates[0],dates[1],dates[2]);
        }
        catch(AssertionError e){
            System.out.println("Error: ValidDate threw an assert error.");
            validdate = false;
        }
        if(validdate){
            DOB = newDOB;
        }
    }
    else{
        System.out.println("Please enter a valid DOB of the form: Month/Day"
                + "/Year using integers.");
    }
}

但是,当我尝试使用无效的 DOB 运行 SetDOB 时, ValidDate 不会为 SetDOB抛出AssertionError 抓住。也没有输出错误消息。我怀疑这个原因与我在 ValidDate SetDOB 中使用try-catch语句有关。但是,我可能犯了一个不同的错误而没有意识到这一点。我希望有人解释我做错了什么以及如何正确完成我的预期任务。如果其他人已经回答了此问题或类似问题,请添加指向其帖子的链接。如果我在遇到链接帖子时发现它多余,我也可能会删除此帖子。

3 个答案:

答案 0 :(得分:2)

然而,真正的问题是你误解了断言的目的。他们表示在执行程序过程中出现了问题,但是表明您对代码的假设是错误的。

当你写这样的东西时

assert someValue != null : "some value should be set"

这意味着您已编写代码的方式someValue以某种方式设置,并且当代码到达assert时,必须被设定。如果有人修改了您的代码,以便它可以在不设置assert的情况下到达someValue,那么断言就会抓住它。

另一方面,您的代码尝试使用断言进行验证。这就是例外的用途:

if (!validmonth) {
    throw new InvalidMonthException("Error: month entry is not valid; must be an integer between (0)1 and 12.");
}

注意:您的代码未捕获断言的最可能原因是您have not enabled them

答案 1 :(得分:1)

断言用于测试代码假定的不变量。如果断言失败,那应该表明你的代码是错误的,从来没有遇到过某种可预测的失败模式。断言不适合后者,因为断言是否在运行时进行评估取决于VM参数。

因此,抓住AssertionError很少是合适的。 (事实上​​,抓住任何Error很少是合适的。)只有在相当特殊的条件下,才有可能从程序本身恢复不正确的方法。

在您的特定情况下,您可能在未启用断言的情况下运行代码。你没有抓住AssertionError,因为没有人被抛出。

答案 2 :(得分:0)

创建自己的异常类,而不是抛出/捕获AssertionError。 不要在SetDOB方法中捕获此异常,而是向setDOB方法添加throws子句。在调用setDOB方法时捕获异常。