异常
什么是异常:有异于正常,和正常情况不一样,有错误出现。阻止当前方法或作用域,称之为异常。
java中的异常体系结构:Throwable(不正常类之首,java中所有不正常类都继承于它)分为Error(指虚拟机错误和线程死锁,出现此类错误程序彻底终结)和Exception(指编码、环境、用户操作输入出现问题)两类。Exception又分为非检查异常(运行时异常RuntimeException,此类错误出现说明代码有问题,应从逻辑上改进代码,此类错误会由java虚拟机自动抛出、自动捕获,分类如下图)和检查异常(引起此类错误的原因多种多样,比如说文件异常、连接异常,需手动添加捕获和处理语句)
java库中丰富的异常种类:
异常处理的作用
处理异常:try-catch以及try-catch-finally
语法:
如果try抛出异常将会发生什么?
1、终止执行
2、程序中的控制权将被移交给catch块中的异常处理程序
例如:
注:try-catch程序语句块之外的语句也会执行
try块会抛出很多种类型的异常,用多重catch块来捕获多种不同类型的异常,进行不同的处理
编写多重catch语句块语法:
注意问题:1、顺序问题:按先小后大,即先子类后父类的顺序来编写多重catch语句块(因为当程序抛出异常时,异常处理系统会就近寻找匹配的异常处理程序,而子类继承于父类,针对于父类的异常处理程序对于子类也是适用的)
有时候用try-catch语句块处理完异常后还需要做一些善后工作,比如说关闭连接。关闭一些打开的文件,这种善后工作用finally语句块实现
package com.imooc.test;
public class TryCatchTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
TryCatchTest tct = new TryCatchTest();
int result = tct.test();
System.out.println("test()方法执行完毕!返回值为:"+result);
int result2 = tct.test2();
System.out.println("我想大声告诉你!test2执行了!!");
}
/**
* divider(除数);
* result(结果);
* try-catch捕获while循环
* 每次循环,divider减一,result=result+100/divider
* 如果:捕获异常,打印输出“抛出异常了!!!”,返回-1
* 否则:返回result
* @return
*/
public int test() {
int divider = 10;
int result = 100;
try {
while (divider > -1) {
divider--;
result = result + 100 / divider;
}
return result;
}catch(Exception e) {
e.printStackTrace();
System.out.println("循环抛出异常了!!!");
return -1;
}
}
/**
* divider(除数);
* result(结果);
* try-catch捕获while循环
* 每次循环,divider减一,result=result+100/divider
* 如果:捕获异常,打印输出“抛出异常了!!!”,返回result=999;
* 否则:返回result
* finally:打印输出“这是finally!!!哈哈!!”,同时打印输出result的值
* @return
*/
public int test2() {
int divider = 10;
int result = 100;
try {
while (divider > -1) {
divider--;
result = result + 100 / divider;
}
return result;
}catch(Exception e) {
e.printStackTrace();
System.out.println("循环抛出异常了!!!");
return result = 999;
}finally {
System.out.println("这是finally!!哈哈!!");
System.out.println("我是Result!!我的值是:"+result);
}
}
}
具体请观看视频:https://www.imooc.com/video/3069
java中的异常抛出以及自定义异常
java中异常的抛出:运用关键字throw和throws
throw:将产生的异常抛出(动作)(写在方法体里面,是一个动词)
throws:声明将要抛出何种类型的异常(声明),可以抛出一种类型或者多种类型,每种类型之间用用逗号隔开
语法:public void 方法名(参数列表)throws 异常列表{
//调用会抛出异常的方法或者:
throw new Exception();
}
如果某个方法调用到会抛出异常的方法,则必须添加try-catch语句来捕获异常,或者添加throws声明来将异常抛出给更上一层的调用者进行处理。
例如:
则需用:
或者添加:
自定义异常:自己定义的异常类型,必须继承java标准类库中相近的异常类型或者是直接继承所有异常的基类——Exception类
java中的异常链
异常链:有时候可以把捕获的异常包装成一个新的异常,然后在新的异常中添加对原始异常的引用,在把新异常抛出,就像链式反应,一个导致另一个
具体请观看视频:https://www.imooc.com/video/1706/0
经验总结:
1、处理运行异常时,采用逻辑去合理规避同时辅助try-catch处理
2、在多重catch块后面,可以加一个(Exception)来处理可能会被遗漏的异常
3、对于不确定的代码,也可以加上try-catch,处理潜在的异常
4、尽量去处理异常,切忌只是简单的调用printStackTrace()去打印输出,应同时进行其他操作,比如业务回滚
5、具体如何处理异常,要根据不同业务需求和异常类型去决定。
6、尽量添加finally语句块去释放占用的资源
以下是一个练习: