JavaSE阶段回顾(7)异常及异常处理

异常

异常(Exception):异常指的是程序运行时发生的不正常事件;异常能够被程序处理,保证程序继续运行下去;例如除数为0、文件没有找到、输入的数字格式不对……
错误(Error):错误程序没法处理,例如内存泄漏。发生错误后,一般虚拟机会选择终止程序运行,程序员需要修改代码才能解决相关错误;
在这里插入图片描述

API树状结构

API中标准异常的顶级父类是Throwable类;
Throwable类有两个子类:Exception和Error;所有异常都是Exception类的直接或间接子类;所有错误都是Error的直接或间接子类;

异常分类

Exception有很多子类;这些子类又可以分为两大类;
即运行时异常和非运行时异常;RuntimeException的子类都是运行时异常,其他的都是非运行时异常;
运行时异常:也称为非检测异常(unchecked Exception), 这些异常在编译期不检测,程序中可以选择处理,也可以不处理。如果不处理运行时会中断,但是编译没问题;
非运行时异常:也称为检测异常(checked Exception), 是必须进行处理的异常,如果不处理,将发生编译期错误;

常见异常

运行时异常经常在编程时发生,了解每种异常的概念有助于高效调试程序;
RuntimeException的子类都是运行时异常;

NullPointerException-空指针异常
发生前提:当对一个空对象,即没有初始化,依然为null的对象调用属性或方法时;
在这里插入图片描述
ArithmeticException-数学异常
发生前提:整数除以0时发生 浮点数除以0 0 无限接近0
在这里插入图片描述
IndexOutOfBoundsException:索引越界异常
,包括字符串索引StringIndexOutOfBoundsException和数组索引ArrayIndexOutOfBoundsException两种;
发生前提:当访问字符串中的字符或者数组中的元素,超过了其长度时;
在这里插入图片描述
NumberFormatException-数字格式异常
发生前提:当把一个字符串转换成数字时,字符串内容不是数字时发生;
在这里插入图片描述
ClassCastException-类型转换异常
发生前提:把父类对象转换成不相关的子类类型时;

在这里插入图片描述

几种常见的运行时异常,可见编译期的时候根本不需要任何处理,编译通过,不过在运行时抛出异常,中断执行;
而非运行时异常恰恰相反,在编译期就会被检测,并强制处理,不处理发生编译错误;

异常处理

Java语言中异常处理主要使用到try/catch/finally三种语句,后面会分别详细学习;
标准异常处理流程如图所示:在这里插入图片描述

把所有可能抛出异常的,或者肯定抛出异常的代码都写到try代码块中;
try{
可能抛出异常的代码块;
}

catch语句紧随try语句后,用来捕获异常并进行处理;
try{
可能抛出异常的代码块;
}catch(异常类型 变量名){
处理异常的代码;
}
会发生三种情况:
1、发生异常被捕获处理;
2、发生异常没有被捕获处理;
3、没发生异常

当try块中中代码抛出了异常对象后,异常处理机制就将这个对象的类型与try后的catch语句中的异常类型进行匹配,如果类型相同,或者抛出的是捕获的子类,就称为匹配成功,那么异常就被捕获,就运行catch块中的语句;否则,称为异常没有被捕获,程序将中断;

catch语句里都写什么代码?
可以写任意需要对异常进行处理的代码;
可以调用异常对象的方法,例如printStackTrace,查看异常发生的栈轨迹

如果try块中有多行代码,有可能抛出多种类型异常,那么可以使用多个catch语句;
注意:catch语句的异常类型必须从子类到父类的顺序,否则编译错误;
从上到下 子类到父类 父类不能放在第一个catch里面

Finally

我们可以发现程序中有这样几种情况:
没抛出异常;
抛出异常并被处理了;
抛出异常没有被处理
如果希望不管什么情况,有一些代码都必须被执行,那么就可以把这些代码写到finally块中;
finally{
不管什么情况,一定被执行的代码块;
}
1、抛出异常并被处理后,finally块被执行;
2、抛出异常未被处理,finally块被执行
3、没有抛出异常,finally块被执行;
4、如果语句中有return,先执行finally里面的代码之后,再去return 返回结束方法
5、System.exit() 直接关闭程序 无法执行
组合情况
必须有try,catch可以有1个或多个,finally最多1个,可以没有,不能有多个;
还有另外一种组合:只有try和finally,没有catch
try{

}finally{

}
如果try块中抛出了异常,则肯定不能被捕获,程序中断,但是finally代码块依然会被执行;

Throw

我们一直说:抛出异常,抛出异常,到底异常怎么抛出的呢?
抛出异常其实就是创建了一个异常对象,然后用throw关键字交给异常处理机制去处理;
throw关键字在方法体中使用,用法如下:
throw 异常对象;

例如:
throw new Exception();

或者
catch(Exception e){
throw e;
}
运行时异常是JVM自动抛出,非运行时异常需要程序员用throw关键字抛出;
如下所示:
上述代码发生编译错误:由于抛出了Exception,是非运行时异常,所以编译期检测,要求必须处理,处理的方式有两种:
使用try/catch/finally进行处理;
不处理,用throws声明异常
当用throw抛出异常后,基本都使用throws进行声明!

throws用在方法声明处,声明该方法可能发生的异常类型;
一个方法如果使用了throws,那么调用该方法时,编译期会提醒必须处理这些异常,否则编译错误;
throws后可以声明多种类型,用逗号隔开即可;
抽象方法也可以使用throws声明该方法可能抛出的异常类型;

一个方法如果使用了throws,那么调用该方法时,编译期会提醒必须处理这些异常,否则编译错误;

依然可以用两种方法处理,可以try/catch,可以继续throws,一般选择try/catch;

如果希望对异常先统一处理,可以处理后再抛出;

调用的时候可以继续处理;

如果希望不管有没有异常都做统一处理,有异常声明抛出,可以使用try/finally

调用的时候可以继续处理;

Finally与return

finally块前有return语句,finally依然被执行;
finally块前有System.exit(0)语句,finally不被执行;
自定义异常
为了能够标记项目中的异常事件,需要使用throw抛出异常;
如果抛出的是API中的标准异常,那么很可能与API中方法抛出的异常混淆,因此需要自定义异常;
项目组根据业务需求定义业务异常,对团队协作开发非常有意义;
自定义异常类非常简单,只要继承API中任意一个标准异常类即可;
多数情况下,继承Exception类;也可以选择继承其他类型异常;
一般自定义异常类中不写其他方法,只重载必要的构造方法;
使用自定义异常与使用API中标准异常一样;
可以用throw抛出自定义异常对象,使用throws声明自定义异常类型;
可以使用try/catch/finally处理异常;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值