Javaexceptiontry-catchexception与IOException

即使try块实际上没有抛出任何exception,下面的代码也可以编译好。

public static void main(String[] args) { try {} catch (Exception e) {} // compiles ok } 

但是如果使用Exception的子类替换catch,则代码将无法编译。

 public static void main(String[] args) { try {} catch (IOException e) {} // won't compile. } 

编译器错误是:IOException的无法访问的catch块。 永远不会从try语句主体抛出此exception。

当Exception和IOException都被检查exception时,为什么会出现这种情况? 我正在使用Java 7。

编译器可以确切地知道代码的哪个部分可以抛出IOException因为它是一个已检查的exception ,因此每个可以抛出此类exception的方法都必须在方法签名中指定它。

另一方面,运行时或未经检查的exception并不是预期的,因为RuntimeException (未经检查的exception的父类)也扩展了类Exception ,所以编译器可以使用它。

Exception具有未经检查的exception的子类( RuntimeException extends Exception )。 Throwable行为类似。 RuntimeExceptionRuntimeException子类的行为类似。 除RuntimeException之外的Exception子类不会。

Manouti的答案似乎是正确的,但根据java文档:

如果catch子句捕获已检查的exception类型E1但是不存在已检查的exception类型E2,则以下所有内容都成为编译时错误:

E2 <:E1对应于catch子句的try块可以抛出E2没有先前封闭的try语句的前一个catch块捕获E2或E2的超类型。 除非E1是类Exception。

抛出Exception实例有一个明确的例子( Exception类是例外,有人可能会说)。 这是Java 5文档,但除非有人另外看到,否则我非常怀疑这已经发生了变化

查看ExceptionIOException的inheritance树

https://docs.oracle.com/javase/7/docs/api/java/lang/Exception.html

https://docs.oracle.com/javase/7/docs/api/java/io/IOException.html?is-external=true

在Java 7中,我没有看到关于Checked / Uncheckedexception的讨论是直接相关的 – 虽然未经检查的exception确实不遵循相同的规则,但未经检查的exception必须从RuntimeExceptioninheritance,而Exception当然不会(是该类的父级)

https://docs.oracle.com/javase/specs/jls/se5.0/html/classes.html#308526

(再次,Java 5文档,但它没有改变) https://docs.oracle.com/javase/specs/jls/se5.0/html/exceptions.html