无法捕获算术异常(尽管捕获IllegalArgumentException很好)

时间:2014-02-15 21:01:25

标签: java exception-handling junit

请看下面的我的构造函数,我正在创建一个字符串的分数:

public Fraction(String str)
    {
        if(str.isEmpty())
        {
            throw new IllegalArgumentException("The str (String) parameter cannot be empty!");
        }
             int[] fractionData= new int[2];
             String[] data = str.split("/");
             try
             {
                 if(data.length==0)
                 throw new IllegalArgumentException("The str (String) parameter cannot be empty");
             }
             catch (IllegalArgumentException ex)
             {
                 System.out.println(ex.toString());
             }
             try
             {
                fractionData[0] = Integer.parseInt(data[0]); 
             }
             catch (IllegalArgumentException ex)
             {
                 System.out.println(ex.toString());
             }

             try
             {
                 fractionData[1] = Integer.parseInt(data[1]);
                 if(fractionData[1]==0) throw new ArithmeticException("Denominator can't be 0");
             }
             catch (ArithmeticException ex)
             {
                 System.out.println(ex.toString());
             }
             fractionData = normalize(fractionData[0],fractionData[1]);
             this.numerator = fractionData[0];
             this.denominator = fractionData[1];
    }

我正在捕获IllegalArgumentException,但无法捕获ArithemticException。我可以成功测试

@Test(expected=IllegalArgumentException.class)
    public void testIllegalArgumenException() throws IllegalArgumentException
    {
        Fraction g =  new Fraction("");
    }
    @Test(expected=ArithmeticException.class)
    public void testArithmeticException() throws ArithmeticException
    {
        Fraction g = new Fraction(1/0);
    }

感谢@ xp500的评论,我已将代码更改为:

public Fraction(String str)
    {
        if(str.isEmpty()) throw new IllegalArgumentException("The str (String) parameter cannot be empty!");
             int[] fractionData= new int[2];
             String[] data = str.split("/");
             if (data.toString().matches("[a-zA-Z]+")) throw new NumberFormatException("only numbers allowed in the string");
             fractionData[0] = Integer.parseInt(data[0]);
             fractionData[1] = Integer.parseInt(data[1]);
             if(fractionData[1]==0) throw new ArithmeticException("Denominator can't be 0"); 
             fractionData = normalize(fractionData[0],fractionData[1]);
             this.numerator = fractionData[0];
             this.denominator = fractionData[1];
    }

它不引用“只允许字符串中允许的数字”,但是如果使用带字母的字符串初始化Fraction并使用带引号的文本抛出其他异常,则停止将Fraction初始化为0/0。对我来说,教训是:除非你实际上与他们一起做,否则不要抓住异常

2 个答案:

答案 0 :(得分:2)

哟正在追赶ArithmeticException,但你不是在追赶它(就像其他例外一样)

答案 1 :(得分:1)

关于代码的一些评论。

您对异常的使用使代码难以理解且难以理解。您应该尝试使用较少的try catch块。我认为如果你按照

的方式写一些内容会更好
if (data.length==0) {
   System.out.println(ex.toString());
   throw new IllegalArgumentException("The str (String) parameter cannot be empty");
}

并且没有捕获该异常,因为您想告诉调用者发生了异常。

此外,fractionData[0] = Integer.parseInt(data[0]);抛出NumberFormatException,而不是IllegalArgumentException

由于您在构造函数中捕获它并且不重新抛出它,因此不会抛出ArithmeticException。请注意,在捕获之后,您的分数将被初始化为无效状态,因为

fractionData = normalize(fractionData[0],fractionData[1]);
this.numerator = fractionData[0];
this.denominator = fractionData[1];

将被执行。同样,您可能想要为

之类的内容重写这些行
if(fractionData[1]==0) {
    System.out.println(ex.toString());
    throw new ArithmeticException("Denominator can't be 0");
}

您不需要在测试方法中编写抛出异常,因为您期望抛出异常,方法本身不会抛出该异常。

我希望有所帮助!