Java异常对于开发人员来说接触是非常频繁,处理好程序的异常也是一门艺术或者说是技术,发现身边很多人其实根本没有搞清楚Java异常。想想自己也当做巩固基础,今天就来把java异常模块总结一下。
本文主要内容:异常的定义
异常的分类
java异常关键字
异常常用代码模板
自定义异常
定义
在计算机的世界里,在运行程序时,发生了意料之外的事件,阻止了程序的正常执行,这种情况被称之为异常。
异常的分类
在JDK中有一套完整异常机制,所有异常都是Throwable的子类,分为Error(知名异常)和Exception(非致命异常)。
Error
Error是一种特殊的异常,它出现标识着系统发生了不可控制的错误,比如:常见的OutOfMemoryError(内存溢出),StackOverflowError栈溢出。
Exception
Exception又分为checked(受检查)和unchecked(非受检查)异常。
checked受检查的异常是需要在程序中显示处理的异常,否则编译失败。在开发过程中遇到这种异常的时候,一般是要么处理掉该异常,要么直接往上抛。常见的checked异常有:SQLException,ClassNotFoundException等。
checked异常还可以分为以下两类异常:无能为力、引起注意型:针对此类型异常,程序无法处理,如果字段超过表字段长度,数据库表字段不存在等造成的SQLException,这时候最好的方式就是打印出异常错误信息,供开发人员排查问题。
力所能及,坦然处理型:发生未授权异常UnAuthorizedException,程序可以跳转至权限申请页面。
可预测异常:就是开发人员可以根据自己的程序大致能猜到的异常。比如:数组越界,IndexOutOfBoundsException、NullPointerException等,面对此等异常,最好解决办法就是开发人员做好相应的边界值校验,或者捕获对应异常就行处理。
需要捕捉异常:比如在使用Dubbo框架进行RPC调用时,容易产生timeout异常DubboTmieoutException,此类异常也是最好显示低捕获,当捕获到相应的异常后可以做一些重试、熔断等操作。
异常关键字
try catch finally throws throw
以上关键字的解释
throws:使用在方法签名参数后 ,向调用此方法的地方抛一个异常。
throw:使用在方法里面,由于某某原因,需要往外跑一个异常,或者是针对某种异常进行转换成自定义异常,然后往外抛自定义异常。
try:不能单独使用,只能结合catch,finally一起使用,try代码块起到见识程序执行过程,如果一旦程序中发生异常则直接跳到catch模块中,如果没有异常发生则直接跳到finally模块中(前提是try+catch+finally)。
catch:结合try一起使用,可以加入finally模块,也可以是多个catch组合.如果try模块中发生异常并且catch(异常类型)刚刚是对应的异常或者范围更大的时候,就会进入catch模块。
finally:结合try使用,或者结合try+catch一起使用。finally模块表示必须执行的模块。不管程序是否发生异常,都会执行finally模块。注意:没有进入finally的情况有:程序执行没有进入try模块、进入try模块,但是程序中出现死循环了或者死锁状态、进入try模块,但是执行了System.exit();
常见代码模板{
() {
}
() {
();
}
() {
{
} ( ) {
} {
}
}
() {
{
} ( ) {
}
}
() {
{
} ( ) {
} ( ){
}
}
() {
{
} ( ) {
} ( ){
} {
}
}
() {
{
} {
}
}
}
自定义异常
在开发过程中难免会想自定义异常,比如说针对某些业务的操作失败,我们如果用其他异常类可能会有歧义,所以使用自定义的异常来和其他异常的区分,也有的时候是针对系统级的,Pay支付模块的异常可以定义成PayException。但是怎么定义呢?Throwable分为Error和Exception,所以如果自定义的异常继承于Error的话行么?因为Error是不可控的,所以通常不会继承与它。通常都是自定义异常继承于Exception或者RuntimeException。如果希望写一个检查性异常类,则需要继承 Exception 类。如果你想写一个运行时异常类,那么需要继承 RuntimeException类。{
( ) {
();
}
}
{
([] ) {
{
();
} ( ) {
System.out.println("test方法报异常," +
e.getLocalizedMessage());
}
}
privatestaticvoidtest(intage)throwsCustomException{
if(age==22) {
thrownewCustomException("这是我的自定义异常");
}else{
System.out.println("不是自定义异常");
}
}
}
运行结果:
test方法报异常,这是我的自定义异常
在工作中使用比较多的自定义方式,把上面的自定义进行改造:
{
;
;
( , ) {
. ;
. ;
}
}
{
([] ) {
{
();
} ( ) {
..( );
}
}
( ) {
( ) {
(, );
} {
..();
}
}
}
运行输出结果:
test方法报异常,异常信息:CustomException{errorCode='300001', errorMsg='这是我的自定义异常'}
注意:异常堆栈信息,不是有多少就打多少,这方面也要悠着点,过多地打印错误日志也是会拖累系统的,能表达清楚就OK了。
异常就说到这里,期待下一期的异常面试题。