0
class Demo{
public static void main(String args[]){
    int x=3,n=5,d=0;
    int ar[]=new int[3];
    String name="Neno";

    System.out.println("Start main");
    try{
        ar[x]=name.charAt(n)/d; //n=5
    }catch(StringIndexOutOfBoundsException e){
        System.out.println("String index Error");
    }catch(RuntimeException e){
        System.out.println("Any runtime Error");
    }catch(ArrayIndexOutOfBoundsException e){
        System.out.println("Array index Error");
    }catch(ArithmeticException e){
        System.out.println("Arithmetic Error");
    }

    System.out.println("End   main");
}
}

我使用此代码过滤了一些异常,但代码中有错误。ArrayIndexOutOfBounds它说要删除and的捕获子句ArithmeticException。是因为catch-clauses的顺序错误出现了吗?当我像这样更改顺序时...

class Demo{
public static void main(String args[]){
    int x=3,n=5,d=0;
    int ar[]=new int[3];
    String name="Niroth";

    System.out.println("Start main");
    try{
        ar[x]=name.charAt(n)/d; //n=5
    }catch(StringIndexOutOfBoundsException e){
        System.out.println("String index Error");
    }catch(ArrayIndexOutOfBoundsException e){
        System.out.println("Array index Error");
    }catch(ArithmeticException e){
        System.out.println("Arithmetic Error");
    }catch(RuntimeException e){
        System.out.println("Any runtime Error");
    }catch(Exception e){
        System.out.println("Any Error");
    }

    System.out.println("End   main");
}
}

此顺序没有错误。谁能解释我这个问题的原因?

4

7 回答 7

5

捕捉异常就像一个接一个的水桶,你必须把更广泛的放在最后。希望下有帮助:

错误的:

 \                           /
  \_____RuntimeException____/

      \                  /
       \__AIOBException_/        //ArrayIndexOutOfBounds

      \                 /
       \__AriException_/        //ArithmeticException

正确的:

      \                  /
       \__AIOBException_/        //ArrayIndexOutOfBounds

      \                 /
       \__AriException_/        //ArithmeticException 

 \                           /
  \_____RuntimeException____/
于 2013-08-16T07:49:39.517 回答
4

您必须在其超类之前捕获特定异常(更广泛的异常,即RuntimeExceptionException

有关相同的问题/答案,请参见此处:Java 中捕获异常的顺序

于 2013-08-16T07:40:43.393 回答
1

是的,catch条款的顺序很重要

这是我的逻辑解释。

当你有

catch(Exception e){
   System.out.println("Any Error");
}
catch(RuntimeException e){
   System.out.println("Any runtime Error");
}

您可以想象,每发生一个异常,它都会被捕获在Exception子句中,RuntimeException永远不会到达/使用另一个块。

于 2013-08-16T07:42:06.157 回答
1

ArithmeticException和extend (ArrayIndexOutOfBoundsException最后两个via ) - 所以在你的第一个代码片段中,永远不会达到捕获。StringIndexOutOfBoundsExceptionRuntimeExceptionIndexOutOfBoundsExceptionArrayIndexOutOfBoundsException

您应该始终首先捕获最具体的异常,然后以最不具体​​的异常结束,就像在第二个代码片段中所做的那样。

干杯,

于 2013-08-16T07:42:59.910 回答
1

是的,顺序很重要。第一个匹配异常的 catch 子句将被执行,其余的被忽略。

作为旁注,通常你不应该抓住RuntimeException. RuntimeException很可能意味着您的逻辑错误或您没有进行适当的检查。

于 2013-08-16T07:43:48.350 回答
0

您需要从最具体到最不具体对例外进行排序。

在您的第一个示例中,位于和之前的块RuntimeException中间的某个位置,它们都是s。 catchArrayIndexOutOfBoundsExceptionArithmeticExceptionRuntimeException

这意味着永远不会到达ArrayIndexOutOfBoundsExceptionor的 catch 块,因为它们扩展了将处理异常的 catch 块。ArithmeticExceptionRuntimeException

通过将异常从最后一个特定到最特定(根据类层次结构)排序,您可以为每个异常提供解决异常的机会。

于 2013-08-16T07:42:53.990 回答
0

应从更具体到泛化捕获异常。换句话说,在超类之前捕获子类的异常。

try
{
int e=33/0;
}

catch(ArithmeticException e)
{
//code here
}

catch (Exception e)
{
}
于 2013-08-16T07:56:34.740 回答