整理一下java里异常的知识,其实异常还是比较简单的,但是很多细节以前没有注意到,在这里梳理一下_
什么是异常
- 程序在运行过程中,有时候会出现一些错误,这些错误会中断当前程序的执行。
- Java把这类导致程序中断运行的错误称为异常
- Java中提供了一系列方法用于捕获、处理这些异常
异常的类型
- Java是完全面向对象的,所以发生异常的时候也就是产生了异常对象
- 所有错误和异常类的根类是
Java.lang.Throwabl
,它的两个重要子类是Error
类和Exception
类 - 说白了Error就是程序搞不定的,比如栈溢出,就系统处理;Exception是程序可以处理的,比如数组越界
Exception类的分类
1. 可查异常(checked)
- 可查异常是指在编译时被强制检查的异常,这种异常时可以预见的,所以必须在程序中进行处理,即或者进行捕获并处理,或者明确抛出给上一级主调进行处理,否则编译不给过
2. 不可查异常(unchecked)
- 不可查异常时指在运行中可能出现的异常,这种异常无法在编译时检查出来,在运行过程中有可能出现也有可能不出现,所以在程序中可以选择捕获处理,也可以不处理
- 这类异常通常都是由程序逻辑错误引起的,所以程序从逻辑角度尽可能避免这类异常的发生
- 不可查异常都是
RuntimeException
类及其子类
Java异常处理机制
1. 抛出异常
- 如果一个方法在数据处理过程中产生了异常,这时该方法会创建一个异常对象交给JVM处理。JVM接到这个异常对象后从这个方法开始按调用栈回溯查找合适的处理程序并执行
2. 捕获异常
- 方法抛异常后,JVM从该方法开始查找该异常处理代码,如果没有则查找调用该方法的方法,直到找到合适的处理代码,如果最后都没有,则JVM终止程序运行
处理异常
- Java要求所有的可查异常必须被捕获或声明抛出,而对于不可查异常
RuntimeException
和错误异常Error
可以忽略(这类一般发生在程序运行期间,可由系统自动抛出,如果不捕获,java也允许该方法不做抛出声明) - 任何java代码都可以抛出异常,使用
throw
语句抛出,如果一个方法不想自己捕获和处理,则在方法声明使用throw
子句抛出 - 捕获异常用
try-catch
语句或try-catch-finally
语句
示例:
try
{//正常数据处理但可能会发生异常的代码}
catch(异常类型1 e)
{//捕获并处理try抛出的异常类型1}
catch(异常类型2 e)
{//捕获并处理try抛出的异常类型2}
finally
{//对try语句块进行后续处理}
try-catch-finally使用规则:
- 逐一执行try语句,如果没有异常,则跳过cath执行finally和后续语句
- 如果try语句块中产生了异常,跳到catch匹配,执行完毕到finally和后续
- 如果catch没有匹配,则JVM处理,但finally还是会执行
- 强调:如果catch里有return语句,但依然会执行finally,不会直接return
throw抛出异常
- 语法格式
throw 异常类对象;
- 执行
throw
语句,会抛出一个Throwable
类型的异常,程序会在throw
语句后立即终止,后面不再执行,然后在包含它的所有try
块中(包括在上层调用方法中)从里向外寻找含有与其匹配的catch子句,例如throw new IOException();
方法声明抛出异常
- 语法格式:
类型 方法名([参数表列]) throws 异常类1,异常类2,...{//…方法体}
- 如果一个方法可能会出现异常,但该方法不想或不能处理这种异常,可以在方法声明时用
throws
关键字来声明抛出异常 - 当方法抛出异常列表中的异常时,方法将不对这些类型及其子类的异常作处理,而是抛给调用该方法的主调方法,由主调方法来进行处理异常。
自定义异常类
- java允许用户根据需要自定义异常类
- 自定义异常类必须继承自
Exception
类 - 自定义异常类的使用与系统定义的异常类的使用方法完全相同。
- 强调:自定义函数继承
Exception
的话,Exception
既包含可检查异常又包含不可检查异常