簡體   English   中英

無法捕獲算術異常(盡管可以很好地捕獲IllegalArgumentException)

[英]Unable to catch Arithmetic exception (Catching IllegalArgumentException fine though)

請在下面查看我的構造函數,我正在根據字符串創建分數:

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

它不引用“僅允許在字符串中使用數字”,而是停止將小數部分初始化為0/0,以防使用帶字母的字符串初始化小數部分並引發其他帶引號的異常。 對我來說,教訓是:除非您確實在與他們做事,否則不要趕在別人面前

您正在捕獲ArithmeticException但您沒有對其進行追溯(像其他異常一樣)

關於代碼的一些注釋。

您對異常的使用使代碼難以閱讀且難以遵循。 您應該嘗試使用較少的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");
}

您不需要在測試方法中編寫throws Exception,因為您希望拋出異常,所以方法本身不會拋出該異常。

希望對您有所幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM