4

我注意到有两种检查异常:

1)

public static void main (String []args)
{
    try{
        //no exception thrown here, it still compiles though.
    }
    catch(Exception e){System.out.println(e);}
}

2)

public static void main (String []args)
{
    try{
         // it does not compile if not written any code which potentially might throw it
    }
    catch(IOException io){System.out.println(io);}
}

是否有任何规则可以预测这种行为?提前知道哪些不是必须在场的吗?希望我已经很清楚地解释了这个问题。谢谢,确实是

4

3 回答 3

4

Java语言规范指出

如果 catch 子句可以捕获已检查的异常类 E1,并且与该 catch 子句对应的 try 块不能抛出作为 E1 的子类或超类的已检查异常类,则这是编译时错误,除非 E1 是异常或异常的超类。

于 2013-09-22T08:00:10.723 回答
3

代码可以很好地编译Exception,因为它是所有CheckedUnchecked异常的超类。因此,带有的catch子句Exception也可以处理未经检查的异常。对于Unchecked exception,编译器无法在编译时检查是否引发了异常。所以,它不会给出任何错误Exception

你甚至可以试试这个RuntimeException

try {

} catch (RuntimeException e) {

}

...这也将编译。

来自JLS 第 11.2.3 节 - 异常检查

如果 catch 子句可以捕获已检查的异常类 E1,并且与该 catch 子句对应的 try 块不能抛出作为 E1 的子类或超类的已检查异常类,则这是编译时错误,除非 E1 是异常或异常的超类。

于 2013-09-22T08:01:49.763 回答
2

Exception是一个检查异常本身,但也是RuntimeException其他未检查异常的超类。

1)在第一种情况下,由于Exception类层次结构包括,编译器无法RunTimeException断定Exception不会在您的块中抛出 an 。所以,它必须允许代码。try { ... }

它可以确认肯定情况(如果您调用声明的方法throws Exception或非运行时子类),但不能确认否定情况。

2)在第二种情况下,它可以在编译时得出结论,IOException不会在try { ... }块中抛出,因为IOException(除自身之外的任何其他已检查异常Exception)不是任何运行时异常的超类。


在以下行为中,我认为这Exception是唯一结合两种类型的特殊情况:

如果抛出:
1A。不需要声明 1B。必须声明

如果声明:
2A。不需要扔 2B。必须扔

如果不抛出:
3A。可能会被抓到 3B。不得被抓

  • 运行时异常:1A2A3A
  • 任何其他检查的异常:1B2B3B
  • 例外:1B2A3A

有关此答案中已检查与未检查异常的更多信息: https ://stackoverflow.com/a/6116020/143295

于 2013-09-22T08:00:55.990 回答