编译器如何识别永远不会从java中的try语句主体抛出异常

时间:2014-06-09 14:07:04

标签: java exception

当我抓住ParseException(代码1)时,编译器会喊“Unreachable catch block for ParseException. This exception is never thrown from the try statement body”。但是当我抓到Exception(代码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();   
}

注意:我在其他地方意外地注意到了这一点。上面只是一个模拟的例子。

2 个答案:

答案 0 :(得分:8)

原因很简单。分配整数可能导致StackOverflowException,或者当前线程可能被中断(导致InterruptedException)。两者都是Exception的子类,因此可以被捕获。

另一方面,ParseException是一个经过检查的异常,您的代码无法抛出该异常。因此,无法到达的捕获块。

enter image description here

答案 1 :(得分:1)

编译器只是为catch强制实施JLS可达性规则;见JLS §14.21

  

如果满足以下两个条件,则可以访问catch块C:

     
      
  1. C的参数类型是未经检查的异常类型或Exception或Exception的超类,或者try块中的某些表达式或throw语句是可到达的,并且可以抛出一个类型可分配给该类型的已检查异常C的参数。 (如果包含它的最内层语句可以访问,则表达式是可到达的。)

         

    表达式的正常和突然完成见§15.6。

  2.   
  3. try语句中没有先前的catch块A,因此C的参数类型与A参数类型的子类相同。

  4.   

正如您所看到的,假定可以访问未经检查的异常的catch,但只有try块直接抛出它才能访问已检查异常的catch,或者调用抛出它的方法。


未经检查的例外规则的基本原理是难以指定未经检查的异常可能发生或可能不发生的情况。 (事实上​​,它取决于JVM的实现,除此之外,你可以说它不可能指定比“未经检查的异常可能发生在任何地方”更紧密......这就是当前的可达性规则松散地暗示着。)