编译器如何识别java中从不从try语句体抛出异常
当我捕获一个编译器如何识别java中从不从try语句体抛出异常,java,exception,Java,Exception,当我捕获一个ParseException(代码1)时,编译器会大叫“ParseException的不可访问的捕获块。这个异常永远不会从try语句体中抛出。”。但当我捕捉到一个异常(代码2)时,它是一个哑巴。为什么会这样 代码1: try { int i = 0; }catch (ParseException e1) { //Unreachable catch block for ParseException. This exception is never thrown from the
ParseException
(代码1)时,编译器会大叫“ParseException的不可访问的捕获块。这个异常永远不会从try语句体中抛出。”。但当我捕捉到一个异常
(代码2)时,它是一个哑巴。为什么会这样
代码1:
try {
int i = 0;
}catch (ParseException e1) { //Unreachable catch block for ParseException. This exception is never thrown from the try statement body
e1.printStackTrace();
}
代码2:
try {
int i = 0;
}catch (Exception e2) { // ............. (dumbed???)
e2.printStackTrace();
}
注意:我不小心在其他地方注意到了这一点。上面的一个只是一个模拟例子。原因很简单。分配整数可能导致StackOverflowException,或者当前线程可能被中断(导致InterruptedException)。两者都是Exception的子类,因此可能会被捕获
另一方面,ParseException是一个已检查的异常,您的代码不能抛出它。因此,无法到达的捕捉块
编译器只是为捕获强制执行JLS可达性规则;看
当以下两项均为真时,可到达捕捉块C:
C参数的类型可能是未检查的异常类型或异常或异常的超类,或者try块中的某个表达式或throw语句是可访问的,并且可以抛出类型可分配给C参数类型的已检查异常。(如果包含表达式的最内层语句是可访问的,则表达式是可访问的。)
有关表达式的正常和突然完成,请参见§15.6
try语句中没有较早的catch块A,因此C的参数类型与A的参数类型相同或是A的参数类型的子类
如您所见,假定未检查异常的捕获是可访问的,但只有当try
块直接抛出或调用抛出该异常的方法时,才能访问已检查异常的捕获
未检查异常规则的基本原理是,很难指定未检查异常可能发生或不发生的情况。(事实上,这取决于JVM实现,除其他外,因此您可能会争辩说,不可能比“未经检查的异常可能在任何地方发生”更严格地指定任何异常……这就是当前的可达性规则松散地暗示的。)我猜这与事实有关,ParseException
是一个已检查的异常,而exception
包括已检查和未检查的异常啊!那个骗子!忘了。谢谢你!实际上,分配i
变量不会在该点导致堆栈溢出。堆栈帧在条目上分配给封闭方法。好的,在这一点上不可能出现异常或错误(可能除了ThreadDeath
…)。为了真正的原因,请阅读我的答案。