异常类是已检查还是未检查的异常?

时间:2018-09-28 07:24:02

标签: java exception

Java docs表示ThrowableRuntimeException以外的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
        }
    }
}

1 个答案:

答案 0 :(得分:3)

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

如果某个方法仅引发检查的异常MySpecialException,那么您只有必须来捕获此异常,如果它会声明throws Exception,则您必须捕获{{1 }}。

但是,使用通用的Exceptionthrows Exception并不是一个好主意,因此无论如何,您都应该使用更具体的异常。

另一方面,由于编译器知道可以在try块中引发哪些检查的异常,因此它可以告诉您有关从不执行的catch块。但是,对于未经检查的异常,情况并非如此。

那么,为什么编译器抱怨catch(Exception e)而不抱怨catch(IOException)?这是因为catch(Exception) 总是是一个已检查的异常,因此编译器知道无法抛出该异常。 IOException 可能也意味着Exception,因此RuntimeException也将捕获那些{}。

catch(Exception)本身的使用方式有所不同,具体取决于使用位置:

  • Exceptionthrows Exception告诉编译器必须处理 checked 异常
  • throw new Exception(...)告诉编译器应处理任何异常,即已检查的未检查的,并且由于未检查的部分,编译器不能抱怨。< / li>

请注意,编译器将catch(Exception)与例如throws Exception出于相同的原因:

  • 如果您声明要在方法中引发特殊检查异常,但不会发生,则编译器可以就此警告您(通常仅是警告,因为throws子句可能由某些接口或超类)。
  • 如果您声明throws IOException,则它将处理该方法,就好像它仅引发已检查的异常一样(即,您必须捕获它们),但是由于此可以包含throws Exception也不会警告您未引发异常。