我的问题与try catch块的语法行为有关
空的尝试块与捕获这样
void fun() {
try {}
catch(Exception e) {}
}
Run Code Online (Sandbox Code Playgroud)
要么
try {}
catch(ArrayIndexOutOfBoundsException e) {}
Run Code Online (Sandbox Code Playgroud)
编译好但编译器抱怨
try {}
catch(IOException e) {}
Run Code Online (Sandbox Code Playgroud)
为什么编译器允许捕获任何类型为Exception或RuntimeException的东西,而它却抱怨带有已检查异常的无法访问的代码?是因为JVM代码可以抛出这些类型吗?JVM怎么可能在空的try块中抛出ArrayIndexOutOfBoundsException?
ysh*_*vit 10
空块是一种特殊情况,不是由JLS专门处理的.什么JLS 不要求是,如果你赶上检查异常,在代码try块必须已经能够抛出该异常(即,它直接扔了或者叫那个被宣布可能把它的方法).
换句话说,有一个专门针对已检查异常的健全性检查,但不会对所有异常情况进行额外考虑.
这在JLS 14.21中有描述,具体来说:
如果由于无法访问语句而无法执行语句,则会发生编译时错误.
...
C如果满足以下两个条件,则可以访问catch块:
要么类型
C的参数是未经检查的异常类型,Exception要么是超类Exception,或者try块中的某些表达式或throw语句是可以访问的,并且可以抛出一个类型可分配给C参数类型的已检查异常.(如果包含它的最内层语句可以访问,则表达式是可到达的.)正常和突然完成表达式见§15.6.
Atry语句中没有先前的catch块,因此C's参数的类型与A's参数类型的子类相同.
添加强调:它表明如果您捕获未经检查的异常类型,则可以访问catch块.
我个人觉得措辞有点令人困惑.稍微重写一下,第一个要点就是说catch子句必须抓住以下一个:
ExceptionThrowable(这是唯一的超类Exception以外Object,你不能赶上)try块可以抛出的已检查异常针对第二子弹警卫catch块的,因为以前不可达catch的那个try.例如:
try {
whatever();
} catch (Exception e) {
handleException(e);
} catch (NullPointerException e) {
// This block is unreachable, because a NullPointerException is an
// Exception and will thus be handled by the previous catch block.
handleNpe(e);
}
Run Code Online (Sandbox Code Playgroud)