下面如何确定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");}
我知道派生类首先出现,基类遵循它们。课程ArithmeticException
和ArrayIndexOutOfBoundsException
来自:
java.lang.Exception
java.lang.RuntimeException
java.lang.ArithmeticException
和
java.lang.Exception
java.lang.RuntimeException
java.lang.IndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
为什么首先放置ArithmeticException
?
答案 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
?
因为这就是该代码的作者想要做的事情。在该代码中,catch
或ArithmeticException
的{{1}}是否排在第一位并不重要,因为它们在类型层次结构中是不同的分支;没有抛出的异常与它们都是赋值兼容的,因此前两个IndexOutOfBoundsException
块的顺序无关紧要。但是,第三个一个,需要是最后,因为catch
和ArithmeticException
都与[{1}}分配兼容。
答案 1 :(得分:0)
我认为这是第一个匹配的,而不是"最具体的一个"。
例如,如果你先捕获(例外e),其他人甚至不会看到。
答案 2 :(得分:0)
它是订单和类型匹配的组合。 执行匹配异常类型的第一个catch块。
答案 3 :(得分:0)
ArithmetcException并非首先置于静态意义上。您观察到的行为更多地与赋值表达式的求值有关:在赋值中,右手边在任何左手边之前被完全评估。
因此,在尝试错误的数组访问之前,尝试除以零 - 并抛出相关的异常。
因此,您的代码不会抛出与数组超出边界访问相关的异常。
答案 4 :(得分:0)
您可以交换两个提到的 catch 子句,结果将是相同的。
由于 ArithmeticException 和 ArrayIndexOutOfBoundsException 之间没有直接的层次关系,因此无关紧要。异常控制从try块线性流动。
另外,请确保您执行的调试打印在其中有一些语义,而不仅仅是"任务1已完成" ...如果这只是一个测试片段而不是一部分,请忽略上述语句长期项目。