我注意到有两种经过检查的例外情况:
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);}
}
有预测这种行为的规则吗?事先知道哪些不是强制性的,它是? 希望我已经非常清楚地解释了这个问题。 谢谢, 确实是的
答案 0 :(得分:4)
如果catch子句可以捕获检查,则是编译时错误 异常类E1并不是try块的情况 对应于catch子句可以抛出一个已检查的异常类 这是E1的子类或超类,,除非E1是Exception或a 超级的超类。
答案 1 :(得分:3)
代码与Exception
编译良好,因为它是所有 Checked 和 Unchecked 异常的超类。因此,带有catch
的{{1}}子句也可以处理未经检查的异常。对于未经检查的异常,编译器无法在编译时检查是否抛出异常。因此,它不会给Exception
带来任何错误。
您甚至可以使用Exception
:
RuntimeException
......这也会编译。
来自JLS Section 11.2.3 - Exception Checking:
如果catch子句可以捕获已检查的异常类E1并且不是对应于catch子句的try块可以抛出作为E1的子类或超类的已检查异常类,则是编译时错误,除非E1是Exception或Exception的超类。
答案 2 :(得分:2)
Exception
本身是一个已检查的异常,但也是RuntimeException
的超类和其他未经检查的异常。
1)在第一种情况下,由于Exception
类层次结构包含RunTimeException
,编译器无法断定Exception
将不< / em>被抛入您的try { ... }
区块。所以,它必须允许代码。
它可以确认肯定的情况(如果你调用声明throws Exception
的方法或非运行时子类),但它无法确认否定的情况。
2)在第二种情况下,可以在编译时结束IOException
块中不会抛出try { ... }
,因为IOException
(除Exception
本身之外的任何其他已检查异常)不是任何运行时异常的超类。
在以下行为中,我认为Exception
是两种类型组合的唯一特例:
如果抛出:
1A。不需要声明或
1B。必须声明
如果宣布:
2A。不需要抛出或
2B。必须抛出
如果没有抛出:
3A。可能会被或抓住
3B。一定不能被抓住
此答案中有关已检查与未检查例外的详细信息:https://stackoverflow.com/a/6116020/143295