Java docs表示Throwable
和RuntimeException
以外的Error
的所有子类都经过 checked 异常。这也包括java.lang.Exception
的直接子类java.lang.Throwable
。
未经检查的异常类是运行时异常类和错误类。
已检查的异常类是未检查的异常类以外的所有异常类。也就是说,除了RuntimeException及其子类以及Error及其子类之外,检查的异常类都是Throwable的所有子类。
仅捕获Exception
的子类,而不捕获Exception
本身的子类,才捕获在try块中未引发的检查异常。这是为什么?
这是否意味着java.lang.Exception
是未选中?
public class CheckedExceptionTest {
public static void good(){ System.out.println("I am good"); }
public static void main(String []args){
try {
good();
} catch (java.io.IOException e) {
// Compile error
// exception IOException is never thrown in body of corresponding try statement
}
}
}
虽然可以编译并正常运行。
public class CheckedExceptionTest {
public static void good(){ System.out.println("I am good"); }
public static void main(String []args){
try {
good();
} catch (java.lang.Exception e) {
// No compile error
}
}
}
答案 0 :(得分:3)
必须声明或捕获任何已检查的异常,因此编译器知道某些代码段可以抛出哪些已检查的异常。
如果某个方法仅引发检查的异常MySpecialException
,那么您只有必须来捕获此异常,如果它会声明throws Exception
,则您必须捕获{{1 }}。
但是,使用通用的Exception
或throws Exception
并不是一个好主意,因此无论如何,您都应该使用更具体的异常。
另一方面,由于编译器知道可以在try块中引发哪些检查的异常,因此它可以告诉您有关从不执行的catch块。但是,对于未经检查的异常,情况并非如此。
那么,为什么编译器抱怨catch(Exception e)
而不抱怨catch(IOException)
?这是因为catch(Exception)
总是是一个已检查的异常,因此编译器知道无法抛出该异常。 IOException
可能也意味着Exception
,因此RuntimeException
也将捕获那些{1>}。
catch(Exception)
本身的使用方式有所不同,具体取决于使用位置:
Exception
或throws Exception
告诉编译器必须处理 checked 异常throw new Exception(...)
告诉编译器应处理任何异常,即已检查的或未检查的,并且由于未检查的部分,编译器不能抱怨。< / li>
请注意,编译器将catch(Exception)
与例如throws Exception
出于相同的原因:
throws IOException
,则它将处理该方法,就好像它仅引发已检查的异常一样(即,您必须捕获它们),但是由于此可以包含throws Exception
也不会警告您未引发异常。