在学习完异常后,小编的JavaSE部分告一个小结,今天我们就来聊聊java中的异常。
异常的定义是程序执行过程中发生的不正常行为(异常不包括语法错误与语义错误【代码本身的错误】),异常是在代码本身语法、语法可能正确的情况下,发生的超出预期的情况,此时,我们就会疑问,为什么是可能?因为异常发生会有两种情况:1.在代码语法与语义完全正确时,遇到某些因素,引发的异常;2.代码存在逻辑错误【语义错误】,间接引发异常。异常有例如算术异常、数组下标越界异常、空指针异常(不指向任何对象却被访问)、克隆异常、类型转换异常等,异常其实是一个类,并且所有的异常继承于Throwable,Throwable又有两个分支,1.Error类【虚拟机JVM层面问题例如JVM内部错误、资源耗尽、栈堆溢出,其本身无法解决这些问题,程序强制终止,无法通过代码处理,只能通过代码预防例如修改代码预防堆溢出、栈溢出,未能避免这些问题必须通过排查根本原因修复代码漏洞或升级硬件资源】2.Exception类【此类异常发生后可以通过代码处理,使程序继续执行】,又分编译时异常(也叫受查异常要求强制显式处理用try-catch捕获处理或throws声明抛出给上层【用throws时方法体内部要么有throw抛出异常要么含已经用thros声明抛出异常的方法(其内部要么含throw抛出要么调用throws声明抛出的异常方法,此方法以此类推)】)、运行时异常(也叫非受查异常不强制编者处理,交给JVM“处理”终止程序,暴露错误),在这两个分支下还有很多类异常,需要的同志可以去查阅一下资料,接下来我们要说说异常的处理。
异常的处理有两种方式1.防御式编程[代码的正常流程相应位置里插入错误处理的代码,整体风格有点混乱] ;2 .事后认错型【EAFP型】,我们先运行代码,出现异常时再通过代码处理。处理异常的流程是
try(要打开资源写在这里,例如:输入输出流、数据库连接、网络连接、缓冲流等,不 不放在大括号而放在这里的好处是try执行完毕或出现异常,这些资源会自动关闭无需手动){
//写可能出现异常的代码
}catch(可能捕获的异常 e){
//处理异常
}finally{
//此处代码一定会执行【不论try是否执行】,在try执行后若没遇到异常则执行finally块若遇到异常捕获处理后执行
}
此种类型,正常流程与错误流程是分开的,涉及到try块的表现形式有三种(catch与fianlly不能同时省略)1.try-catch 2.try-catch-finally 3.try-finally。此外,java异常处理用到的5个关键字:throw、try、catch、finally、throws,这时你肯定会好奇,这些关键字用来干什么?君且听鄙人娓娓道来。
异常抛出用throw关键字,手动抛出指定异常,【这里插一句手动抛出异常与JVM触发异常的区别是手动抛出的异常一般是自定义异常(throw new······)】,注意throw必须写在方法体内部,抛出对象必须是Exption或Exption子类对象,抛出RunTimeException或其子类【非受查异常】,可以不用处理,抛给JVM处理(这里的处理含义是终止程序),抛出的是编译时异常必须要处理(这里处理的含义是异常发生后让程序正常运行),异常一旦遇到抛出,其后的代码不会再被执行(因为抛出异常后捕获后执行catch后的代码或一直抛给JVM,直接终止),未遇到异常不会触发抛出,后面的代码可被执行。
异常的声明,用关键字throws声明当前方法可能会抛出异常,异常没被处理,要么被try-catch捕获处理,要么留给JVM处理(非受查异常)。throws必须跟在方法参数列表之后,声明的异常必须是Exception或Exception子类,方法内部如抛出多个异常,throws后必须跟多个异常类型,用逗号隔开,若抛出异常有父子关系,直接声明父类异常即可,其方法体内部必须有throw抛出异常或调用含throws的方法(此方法内部也面临着两种选择1.throw抛出2.继续调用含throws的方法)。
抛出异常后用try-catch处理异常时,可用e.printStackTrace()打印栈上的追踪信息,不会同时抛出多个异常,因为遇到一个异常就去解决一个异常,后面来不及处理后面抛出的异常,无论catch有多少个,只会匹配一个去执行。用catch捕获不同类型的异常,catch(异常类型1|异常类型2 e){
}//处理可能会出现两种不同种类的异常,catch(Exception e)//可捕获所有Exception子类异常(一般用于不知Exception类异常的异常类型或已经catch了一种异常,为以防万一,用它兜底),try中有多个不同的异常对象,必须用多个catch来捕获处理,这与只匹配一个catch,后面代码不执行,不矛盾,因为这里说的含义是try多个异常中,只遇到其中一个异常,与catch对应匹配。
到这里我们还差对finally的详细解释,finally代码块不管是否发生异常,都会被执行,一般用于资源的释放(善后工作),一些特殊的代码,不论程序是否发生异常,都需要被执行,就会用到它。例如:数据库链接、IO流、网络连接等,finally可以用于资源回收,由于异常发生有些语句并不能执行到,放入finally之后就可以解决,一般不建议在finally中写return
处理异常先是方法本身去处理,不处理交给调用此方法的代码处理,还不处理交给JVM直接使程序异常终止。(throw与throws的区别是,throw抛出指定异常(若自定义异常需要建立对应的异常类继承Exption且构造方法用super()初始化父类),throws是声明可能抛出的异常)。最后,让我们来总结一下异常处理流程:1.先执行try中代码,出现异常就会执行catch中的代码匹配异常,执行finally,未出现就跳过catch执行finally,抛出异常后上层没有处理异常,继续跑得调用它的代码,到main方法也没有处理,就交给JVM“处理”。(今天的异常就说到这里,如有误,请告诉小编,小编太想进步了,谢谢~)

被折叠的 条评论
为什么被折叠?



