java存在很多异常类,Java语言设计者将异常划分为两类:Error和Exception
并且定义了基类java.lang.Throwable作为所有异常的超类
体系结构大致如下:
Throwable:有两个重要的子类:Exception(异常)和Error(错误)
一、Error(错误):是程序中无法处理的错误,表示运行应用程序中出现了严重的错误,此类错误一般表示代码运行时jvm出现问题,通常有Virtual MachineError(虚拟机运行错误)、NoClassDefFoundError(类定义错误)等,比如说当jvm耗完可用内存时,将出现OutOfMemoryError。此类错误发生时,JVM将终止线程。
这些错误是不可查的,非代码性错误。因此,当此类错误发生时,应用不应该去处理此类错误
二、Exception(异常):程序本身可以捕获并且可以处理的异常 ,Exception这种异常又分为两类:运行时异常和编译异常
1.运行时异常(不受检异常):RuntimeException类极其子类表示JVM在运行期间可能出现的错误。比如说试图使用空值对象的引用(NullPointerException)、数组下标越界(ArrayIndexOutBoundException)。此类异常属于不可查异常,一般是由程序逻辑错误引起的,在程序中可以选择捕获处理,也可以不处理
2.编译异常(受检异常):Exception中除RuntimeException极其子类之外的异常。如果程序中出现此类异常,比如说IOException,必须对该异常进行处理,否则编译不通过。在程序中,通常不会自定义该类异常,而是直接使用系统提供的异常类
三、java的所有异常可以分为可查异常(checked exception)和不可查异常(unchecked exception)
1.可查异常:编译器要求必须处理的异常。正确的程序在运行过程中,经常容易出现的、符合预期的异常情况。一旦发生此类异常,就必须采用某种方式进行处理。除RuntimeException及其子类外,其他的Exception异常都属于可查异常。编译器会检查此类异常,也就是说当编译器检查到应用中的某处可能会此类异常时,将会提示你处理本异常——要么使用try-catch捕获,要么使用throws语句抛出,否则编译不通过
2.不可查异常:编译器不会进行检查并且不要求必须处理的异常,也就说当程序中出现此类异常时,即使我们没有try-catch捕获它,也没有使用throws抛出该异常,编译也会正常通过。该类异常包括运行时异常(RuntimeException极其子类)和错误(Error)
四、异常处理流程
在java应用中,异常的处理机制分为抛出异常和捕获异常
抛出异常:当一个方法出现错误而引发异常时,该方法会将该异常类型以及异常出现时的程序状态信息封装为异常对象,并交给本应用。运行时,该应用将寻找处理异常的代码并执行。任何代码都可以通过throw关键词抛出异常,比如java源代码抛出异常、自己编写的代码抛出异常等。
捕获异常:一旦方法抛出异常,系统自动根据该异常对象寻找合适异常处理器(Exception Handler)来处理该异常。所谓合适类型的异常处理器指的是异常对象类型和异常处理器类型一致。
对于不同的异常,java采用不同的异常处理方式:
1.运行异常将由系统自动抛出,应用本身可以选择处理或者忽略该异常。
2.对于方法中产生的Error,该异常一旦发生JVM将自行处理该异常,因此java允许应用不抛出此类异常。
3.对于所有的可查异常,必须进行捕获或者抛出该方法之外交给上层处理。也就是当一个方法存在异常时,要么使用try-catch捕获,要么使用该方法使用throws将该异常抛调用该方法的上层调用者。