Exception 类是检查异常还是非检查异常?

SMU*_*hah 4 java exception

Java文档说,Throwable除 和 之外RuntimeException的所有子类Error都是受检查异常。这还包括 的java.lang.Exception直接子类java.lang.Throwable。

未经检查的异常类是运行时异常类和错误类。

检查异常类是除非检查异常类之外的所有异常类。也就是说,检查异常类除了RuntimeException及其子类和Error及其子类之外,都是Throwable的子类。

捕获未在 try 块中抛出的已检查异常只会为 的子类带来编译错误Exception,而不会为其Exception自身带来编译错误。这是为什么?

这是否意味着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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然编译并运行良好。

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Tho*_*mas 6

任何检查异常都必须声明或捕获,因此编译器知道某些代码可以抛出哪些检查异常。

如果一个方法只抛出已检查的异常MySpecialException,那么你只需要捕获它,如果它声明throws Exception那么你必须捕获它Exception。

但是,使用通用的throws Exceptionorcatch(Exception e)很少是一个好主意,因此无论如何您应该使用更具体的异常。

另一方面,由于编译器知道哪些已检查异常可以在 try 块内抛出,因此它能够告诉您永远不会执行的 catch 块。但对于未经检查的异常而言,情况并非如此。

那么为什么编译器会抱怨catch(IOException)但不抱怨catch(Exception)呢?这是因为IOException always是一个受检查的异常,因此编译器知道它不能被抛出。Exception 也可以表示 a RuntimeException,因此catch(Exception)也会捕获那些(如果有的话)。

Exception根据使用位置的不同,其本身的处理方式也有所不同:

  • throws Exception或者throw new Exception(...)告诉编译器必须处理已检查的异常
  • catch(Exception)告诉编译器任何异常,即检查或未检查的异常都应该被处理,并且由于未检查的部分,编译器不能抱怨。

请注意,出于相同的原因,编译器将采用throws Exception与eg不同的方式处理:throws IOException

  • 如果您在方法中声明要抛出一个特殊的检查异常,但它没有发生,那么编译器能够警告您(通常只是一个警告,因为 throws 子句可能由某些接口或超类指定)。
  • 如果您声明,throws Exception那么它将处理该方法,就好像它只会抛出已检查的异常(即您必须捕获它们),但由于这也可能包含RuntimeExceptions,因此它无法警告您未抛出异常。