2017-12-18 334 views
1

为什么下面的代码编译正常,但被调用的方法不需要抛出Exception?是不是Exception检查异常,而不是未经检查的异常?请澄清。异常不需要被抛出,但IOException异常

class App { 
    public static void main(String[] args) { 
     try { 
      amethod(); 
      System.out.println("try "); 
     } catch (Exception e) { 
      System.out.print("catch "); 
     } finally { 
      System.out.print("finally "); 
     } 
     System.out.print("out "); 
    } 
    public static void amethod() { } 
} 

如果我想使用一个IOexception尝试捕捉(checked exception)时,该方法被调用需要扔IOException。我明白了。

import java.io.IOException; 

class App { 
    public static void main(String[] args) { 
     try { 
      amethod(); 
      System.out.println("try "); 
     } catch (IOException e) { 
      System.out.print("catch "); 
     } finally { 
      System.out.print("finally "); 
     } 
     System.out.print("out "); 
    } 
    public static void amethod() throws IOException { } 
} 
+2

我认为你的理解是倒退的。 'throws'声明的目的是列出被调用者抛出的选中的异常,而不是被调用者捕获的异常。 –

回答

1

不是 '例外' checked异常,而不是一个未经检查的异常?

是的。

但即使我们知道该方法本身不会丢弃Exception本身,代码catch(Exception e){仍然可以执行。 try块中的代码仍然可以抛出继承自Exception的内容。这包括RuntimeException及其子类,它们未被选中。

catch(IOException e){另一方面,只能捕获检查异常。 (Java不允许多继承,所以任何属于IOException的子类都不可能是RuntimeException的子类。)编译器可以很容易地发现try块中的任何代码都不可能抛出IOException(因为任何引发检查异常的方法都必须明确地说明),从而允许它标记代码。

+0

完美!容易明白 –

1

您正在观察的行为来自Java语言规范在这种情况下专门处理Exception的事实。据§11.2.3

这是一个编译时错误,如果catch子句能赶上检查异常E类,这是不是相当于catch子句try块的情况下可以抛出除E 为ExceptionException的超类之外的作为E 的子类或超类的检查异常类。

这是合理的,因为Exception(和它的超类Throwable)可以被用来捕捉延伸RuntimeException也异常。由于运行时异常总是可行的,编译器总是允许Exception出现在catch子句中,而不管是否存在已检查的异常。