java高级——Exception异常类基本解读
java高级——Exception异常类基本解读
前情提要
上一篇文章我们探索了Collection集合中的Set,相对来说比较轻松,因为底层是基于Map实现的,只要对Map足够了解,Set只需要简单看一下,还是建议大家看一下Map的底层源码,对之后更好的使用集合有很大帮助。
java高级——Collection集合之Map探索(包含红黑树,Map的底层实现原理及相关类如LinkedHashMap等多中介绍,满满的干货)
文章介绍
这一篇我们来讲一下java中的异常,虽然我们在开发中一直在使用和遇到过异常,但对异常并没有过真正的了解,到底异常分为哪几类
?有哪些异常我们需要注意
?怎么有效的避免异常
?这一篇文章将带领大家解决这些问题。
继承结构
单从继承结构来说很简单,Exception继承了Throwable,Throwable实现了Seriaizeble接口
,而源码经过一段时间的查看,发现研究的意义不大,很多都是基于非常底层的知识,重要的还是怎么更好的使用和认识异常
。
异常详解
1. 异常的定义
异常在我们普遍的认知就是错误,专业来说就是在程序中出现了不正常或不按预期执行而导致程序的中断
,这种现象称之为异常
。
2. 异常的分类
异常我们主要分为三大类:
非受查异常
(也叫非受控异常
、一般异常):
在java中这种异常我们习惯性称之为RuntimException
(运行时异常
),这种异常在程序运行中出现
,编译是正常通过的,一般我们只能在方法中用throws抛出异常
或者使用try catch语句进行捕捉
。受查异常
(也叫受控异常
):
在java中这种异常通常在编译中就发现了
,如果不处理则无法编译通过
,最常见的就是进行IO操作时必须进行异常处理,比如FileNotFoundException
。- 错误(Error):
注意,这是异常的一种
,而Error如果出现那就不得了啦,程序多半是崩了
,需要进行重启,比较典型的就是OutOfMemoryError
(内存不足)。
3.3 异常的处理机制
3.3.1 try catch finally语句
开发中最常用的异常处理机制是try catch语句,之后在catch语句中进行发生异常后的一些操作,如下:
这里我们需要注意以下几点:
- 异常发生后,
异常之后的代码不会执行
; finally语句块中的代码一定会执行
,一般用于关闭某些资源
,如输入输出流;- catch语句中一般写的是发生异常后的一些操作,一般
不建议在catch语句块中写return语句
;
为什么不建议在catch中写return语句,上面给出了原因,当finally中也出现return后
,catch语句中的return是不会执行的
,所以开发中大多数在catch都是当异常发生后做的一些赋值操作,让程序正常运行,给用户返回一个友好的提示。
3.3.2 throw关键字
throw使用也是比较方便的,当我们想要在一种情况抛出异常,让程序直接结束并给前台一个错误提示,但又不想写return语句的时候
,throw就派上用场了。新手可能在Service中想要返回一个错误提示,就必须给controller一个返回值返回到前台,其实有时候不需要那么麻烦。
这是一种简单的方式,直接用throw抛出异常
,让程序直接结束返回
,但这实际上还是有返回值,只是相对方便一些,还有一种就是全局捕捉异常
,当我们前台的Ajax请求或者axios请求发出后,后台统一对返回值进行处理,如果发生异常,直接将异常信息捕捉,丢给前台即可。
全局捕捉异常是非常有必要的,代码统一管理,没有必要在每个controller中单独处理了,当然现在的前后端分离项目都有这种机制,一般我们是不需要操心的,只需要使用即可,如果想要详细了解,需要研究一下springboot或者springmvc了,这里不做赘述。
3.3.3 throws关键字
throws一般是写在方法上的,用于统一处理方法中的异常
,但是非必要不建议这么用
,因为不好进行捕捉
,虽然控制台能打印出来。
4. 浅谈如何有效的避免异常的发生
在真实的业务场景中,我们习惯将异常分为阻断性异常
和非阻断性异常
,阻断性异常就是你没有正确的处理异常,导致用户看到了一些奇奇怪怪的报错信息
,比如用户页面提示了一堆后台的错误堆栈信息
,或者直接导致页面奔溃
,一般出现这种错误事儿就大了,是要挨骂的哦(别问,问就是挨过骂)
。非阻断性异常一般就是虽然程序报错了,也没给用户返回正确的信息,但是你的页面正常
,也给了错误提示,数据也进行了回滚,这种一般没有什么,改一改就好。
开发中除了全局进行异常处理
,我们在代码编写过程中也要注意,非常有效的手段就是使用工具类
,NullException估计是一大噩梦
,在判空时尽量使用StringUtils工具类或者ObjectUtils工具类,这些一般的第三方jar包都有,比如huttol工具包
,还有各种工具类,这样能大大避免我们的错误。最重要的还是,不要完全相信自己的代码
,比如我用UUID在数据库中查询一个pojo,这一定会有值,错了,年轻了,虽然这个UUID一定会对应到这条数据,但有可能数据库出问题了呢?有可能多线程操作导致数据被删除了呢?所以,一定要进行判空,这是兵家大忌
。
5. 自定义异常
这里简单说一下自定义异常,只是给大家留个书面印象,自定义异常也是优化我们开发的手段,比如你的后台模块较多,薪酬啊,绩效啊等,这时候自定义异常就显得尤为重要,我们可以给指定模块自定义一个异常,这个模块统一使用这个异常,在后面排查的时候是比较有用的。
一般大的系统都会有一个后台管理,而这个管理就有程序报错的统计,我们的系统对这一块有比较好的管理,如果程序出错,后台会进行捕捉,入库,管理员能在页面进行错误信息查看,有错误的堆栈信息,哪一个模块发生的错误,对应的账号是哪个,排查起来很方便。
这一篇文章只是简单说一下,之后说到框架的时候会详细进行说明。
6. 常见的RuntimeException
- NullPointerException:尝试访问或操作 null 对象时抛出。
- ArrayIndexOutOfBoundsException:尝试访问数组的非法索引时抛出。
- IllegalArgumentException:方法被传递了不合法或不适当的参数时抛出。
- IOException:在进行 I/O 操作时可能抛出的各种异常的超类。
- SQLException:在进行数据库操作时可能抛出的异常。
- NumberFormatException :类型转换异常。
总结
好了,这篇文章到这里就告一段落,后面在框架的解析中会将其再次带出,下一篇我们将解析IO流。
原文地址:https://blog.csdn.net/weixin_48588897/article/details/140673920
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!