如何确定哪个捕获块首先出现?

时间:2017-02-12 11:20:30

标签: java exception try-catch

下面如何确定catch块?

try{  
    int a[]=new int[5];  
    a[5]=30/0;  
}  
catch(ArithmeticException e){System.out.println("task1 is completed");}  
catch(ArrayIndexOutOfBoundsException e){System.out.println("task 2 completed");}  
catch(Exception e){System.out.println("common task completed");}  

我知道派生类首先出现,基类遵循它们。课程ArithmeticExceptionArrayIndexOutOfBoundsException来自:

java.lang.Exception
    java.lang.RuntimeException
        java.lang.ArithmeticException 

java.lang.Exception
    java.lang.RuntimeException
        java.lang.IndexOutOfBoundsException
            java.lang.ArrayIndexOutOfBoundsException 

为什么首先放置ArithmeticException

5 个答案:

答案 0 :(得分:4)

它们按照您提供的顺序进行测试:第一个catch的类型是抛出的异常类,或者它的超类是使用的类。这在JLS§14.20.1

中有所描述
  
      
  • 如果由于抛出值V而导致try块的执行突然完成,则可以选择:

         
        
    • 如果V的运行时类型与{§5.2}的catch语句的任何try子句的可捕获异常类兼容,那么第一个(最左边)这样的选择了catch子句。将值V分配给所选catch子句的参数,并执行该catch子句的块,然后有一个选项:

           
          
      • 如果该块正常完成,则try语句正常完成。

      •   
      • 如果该块因任何原因突然完成,则try语句会因同样的原因而突然完成。

      •   
    •   
    • 如果V的运行时类型与try语句的任何catch子句的可捕获异常类不兼容,那么try语句会因为抛出而突然完成值V。

    •   
  •   

继续你的问题......

  

为什么首先放置ArithmeticException

因为这就是该代码的作者想要做的事情。在该代码中,catchArithmeticException的{​​{1}}是否排在第一位并不重要,因为它们在类型层次结构中是不同的分支;没有抛出的异常与它们都是赋值兼容的,因此前两个IndexOutOfBoundsException块的顺序无关紧要。但是,第三个​​一个,需要是最后,因为catchArithmeticException都与[{1}}分配兼容。

答案 1 :(得分:0)

我认为这是第一个匹配的,而不是"最具体的一个"。

例如,如果你先捕获(例外e),其他人甚至不会看到。

答案 2 :(得分:0)

它是订单和类型匹配的组合。 执行匹配异常类型的第一个catch块。

答案 3 :(得分:0)

ArithmetcException并非首先置于静态意义上。您观察到的行为更多地与赋值表达式的求值有关:在赋值中,右手边在任何左手边之前被完全评估。

因此,在尝试错误的数组访问之前,尝试除以零 - 并抛出相关的异常。

因此,您的代码不会抛出与数组超出边界访问相关的异常。

答案 4 :(得分:0)

您可以交换两个提到的 catch 子句,结果将是相同的。

由于 ArithmeticException ArrayIndexOutOfBoundsException 之间没有直接的层次关系,因此无关紧要。异常控制从try块线性流动。

另外,请确保您执行的调试打印在其中有一些语义,而不仅仅是"任务1已完成" ...如果这只是一个测试片段而不是一部分,请忽略上述语句长期项目。