我自己练习了一些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语句有关。但是,我可能犯了一个不同的错误而没有意识到这一点。我希望有人解释我做错了什么以及如何正确完成我的预期任务。如果其他人已经回答了此问题或类似问题,请添加指向其帖子的链接。如果我在遇到链接帖子时发现它多余,我也可能会删除此帖子。
答案 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方法时捕获异常。