发生细节:
Java将发生的错误封装到对象(ArrayIndexOutOfBoundsException等)中,JVM需要把问题反馈给调用者(如果是主函数中的函数则反馈给主函数),之后结束此函数,最后,主函数收到异常则会继续抛出调用者JVM,JVM收到后,做出了最后的处理方式,将问题的所有信息打印到屏幕上,同时让程序提前终止
异常的应用:
- 创建一个异常对象,封装 一些提示信息
- 需要将这个对象告知调用者,通过throw完成
- throw用在函数内,抛出异常对象,可以结束函数
手动定义异常:
- 需要定义一个类继承Throwable(超类)中Exception子类的RuntimeException子类,并在该类中的构造函数传入参数至父级
//继承Exception和RuntimeException的区别:程序如果出现问题,Java认为这个程序存在安全隐患,需要捕获或者声明出来(解决或者让调用者知道),RuntimeException不需要捕获不需要声明的原因是:不是功能本身发生的异常,而是因为调用者导致功能运行失效,需要通过异常来体现,但是这个不需要声明出来(声明的目的是为了让调用者进行处理,不声明的目的是不让调用者进行处理,为了让程序停止,让调用者看到现象,并进行代码的修正)原理:异常分两种,1.编译时异常,编译器会检测异常,需要声明。2.运行时异常,编译器不会检测异常,不需要声明,可以声明,让调用者给出处理方式
声明(将问题标识出来,报告给调用者)
如果定义功能时有问题发生需要报告给调用者,可以通过在函数上使用throws关键字进行声明
如:void show() throws Exception
而当调用了声明异常的方法时,必须有处理方式,要么捕获,要么声明,可以在调用者继续声明,直到到JVM中打印出来
捕获
Java对异常有针对性的语句进行捕获
try {
语句1; //假设语句1有异常,当try检测到了之后,跳过语句2,直接执行catch语句块
语句2;
} //需要被检测的代码块
catch(异常类 变量) //抛出什么问题就定义什么问题的引用
{
语句1;
语句2;
} //异常处理的语句
fanally{} //一定会执行的语句
如果错误有多个,需要多个catch来获取
异常转换
抛出的问题应该符合方法的解决,此时可以将异常转换
throw和throws
区别:
- throw用在函数内,throws用于函数上
- throw抛出的是异常对象,throws用于进行异常类的声明,后面异常类可以有多个,用逗号隔开
finally的使用
定义
有一些代码,必须要执行,因为异常会引发程序跳转,导致有些语句执行不到,异常捕获处理时,Java提供解决方案:finally就是解决这个问题的,这个代码块中存放的代码一定会被执行。(即使catch中的最后一句为return,也会先执行finally再结束程序)
特殊情况
System.exit(0); 退出JVM,finally也不会执行
适用场景
只要程序中适用到了具体的资源(数据库链接,IO资源,网络链接socket等),需要释放,都需要定义在finally中。即,无论问题发生与否,代码都要执行的放入finally中。
try catch finally 组合方式
- try catch :对代码进行异常检测,并对检测的异常递给catch处理 异常捕获处理了(不用throws)
- try finally:对代码进行异常检测,但检测到异常后没有catch,所以会被默认JVM抛出 异常时没有捕获处理,但是功能所开启的功能需要关闭,所以finally (需要用throws)
- try catch finally:检测异常,并传递给catch处理,并定义资源释放
- try catch catch ··· catch finally:检测异常,并转移至对应的catch处理,并定义资源释放
异常在继承或实现中的细节(重点)
- 子类在覆盖父类方法时,如果父类方法声明异常,子类只能声明该父类的异常或者该父类异常的子类(多态),或者不声明
- 当父类方法声明多个异常时,子类只能覆盖时只能声明多个异常的子集
- 当父类中被覆盖的方法没有异常声明时,子类无法声明异常(父类和接口都有这种情况)
当父类或接口中没有声明异常时,但是子类可能发生异常,那么子类无法throws声明,只能catch捕获,如果catch处理不了,那么只能在catch中继续使用throw抛出,但是只能将异常转换成RuntimeException子类抛出(告知调用者问题所在)
新功能
try的新应用
try(){}
只需要将操作关闭的资源的部分定义在()中,可以完成资源的自动释放(可以舍去finally中资源的关闭,一般用于IO流中),但是,()内只能定义实现了Autocloseable接口的子类
异常合并
当try中可能发生多个用同一种方式处理的异常时,我们可以将其定义在一个catch中,异常对象用|分隔开即可,如:
try{}
catch(IOException | ArrayIndexOutOfBoundsException e) {
解决方法;
}
错误(运行时,除了异常还有错误)
区别
异常:通常发生后有针对性的处理方式
错误:通常发生后没有针对性的处理方式
原因:error的发生往往都是系统级问题,都是JVM所长系统发生并反馈给JVM,只能修正代码