第一节:异常分类
示例图
ThrowableErrorException虚拟机错误内存溢出线程死锁检查异常非检查异常IO异常SQL异常空指针异常数组下标越界算术异常类型转换异常
补充说明
Throwable:是所有异常的父类
Error:是程序无法处理的错误,表示运行应用程序中较严重的问题
Exception:是程序本身可以处理的异常,异常处理通常指针对Exception类型的异常
非检查异常:程序运行时可能出现的异常,编译器不要求强制处理
检查异常:编译器要求必须处置的异常
第二节:异常处理机制
当方法中出现错误引发的异常时,方法会创建异常对象并交付给运行时系统进行处理,当运行时系统捕获到异常时,系统会去寻找适合的处理器(catch块),如果找到了与抛出异常匹配的处理器,就会执行相关的处理逻辑;如果未找到,那么运行时系统将会终止运行,程序也将会终止。
第三节:try-catch-finally
方案一
```publicclassDemo{
publicstaticvoidmain(String[]args) {
Scannerinput=newScanner(System.in);
try{
System.out.println("请输入第一个整数");
intone=input.nextInt();
System.out.println("请输入第一个整数");
inttwo=input.nextInt();
System.out.println("one/two="+(one/two));
}catch(Exceptione) {
System.out.println("程序错误");
e.printStackTrace();// 打印错误信息
}finally{
System.out.println("======运算结束======");
}
}
}
```
补充说明
try块:用于捕获异常
catch块:用于处理try捕获到的异常
finally块:无论是否发生异常,代码总能被执行
异常产生后,try块产生异常后面的代码将不再被执行,相对应的catch块中代码将被执行
try块后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块,catch块必须搭配try块使用
方案二
publicclassDemo{
publicstaticvoidmain(String[]args) {
Scannerinput=newScanner(System.in);
try{
System.out.println("请输入第一个整数");
intone=input.nextInt();
System.out.println("请输入第一个整数");
inttwo=input.nextInt();
System.out.println("one/two="+(one/two));
}catch(ArithmeticExceptione) {
System.out.println("除数不能为零");
e.printStackTrace();
}catch(InputMismatchExceptione) {
System.out.println("请输入整数");
e.printStackTrace();
}catch(Exceptione) {
System.out.println("程序错误");
e.printStackTrace();
}finally{
System.out.println("======运算结束======");
}
}
}
补充说明
一个try块后,不能重复捕获相同类型异常,即catch块中异常类型不能相同
使用多重catch块时推荐补充一个父类异常Exception,避免匹配不到异常类型而造成程序终止
使用多重catch块时,Exception异常建议写在最后,使得其它异常正常执行
特别说明
System.exit()方法可以阻止finally块被执行
System.exit(0)是正常退出程序,而System.exit(1)或者说非0表示非正常退出程序
方案三
publicclassDemo{
publicstaticvoidmain(String[]args) {
intresult=test();
System.out.println(result);
}
publicstaticinttest() {
Scannerinput=newScanner(System.in);
try{
System.out.println("请输入第一个整数");
intone=input.nextInt();
System.out.println("请输入第一个整数");
inttwo=input.nextInt();
returnone/two;
}catch(Exceptione) {
System.out.println("程序错误");
e.printStackTrace();
return0;
}finally{
System.out.println("======运算结束======");
return-1;
}
}
}
补充说明
当try、catch中包含return语句时,程序按正常逻辑返回return结果
当try、catch、finally 中都包含return语句时,无论程序是否出现异常,最终都将返回finally块中return结果,除了return语句,其它代码按逻辑正常执行
强烈不建议在finally块中添加return语句,莫得意义
第四节:throws
方案一
publicclassDemo{
publicstaticvoidmain(String[]args) {
try{
intresult=test();
System.out.println(result);
}catch(ArithmeticExceptione) {
System.out.println("除数不允许为零");
e.printStackTrace();
}catch(InputMismatchExceptione) {
System.out.println("请输入整数");
e.printStackTrace();
}catch(Exceptione) {
e.printStackTrace();
}
}
publicstaticinttest()throwsArithmeticException,InputMismatchException{
Scannerinput=newScanner(System.in);
System.out.println("请输入第一个整数");
intone=input.nextInt();
System.out.println("请输入第一个整数");
inttwo=input.nextInt();
System.out.println("======运算结束======");
returnone/two;
}
}
补充说明
异常一定要被抛出后才能被捕获
在方法声明处,throws声明将要抛出的异常类型,后可接一个或多个异常类型,异常间用逗号分隔
当throws抛出异常时,方法不会处理这些被抛出类型及其子类型的异常,而是将异常抛向此方法的调用者,由调用者来处理异常
调用者可以处理被抛出异常类型的父类异常(通常也会这样做,避免匹配不到异常类型)
被处理的父类异常通常放在最后面
方案二
publicclassDemo{
publicstaticvoidmain(String[]args) {
try{
intresult=test();
System.out.println(result);
}catch(ArithmeticExceptione) {
System.out.println("除数不允许为零");
e.printStackTrace();
}catch(InputMismatchExceptione) {
System.out.println("请输入整数");
e.printStackTrace();
}catch(Exceptione) {
e.printStackTrace();
}
}
publicstaticinttest()throwsException{
Scannerinput=newScanner(System.in);
System.out.println("请输入第一个整数");
intone=input.nextInt();
System.out.println("请输入第一个整数");
inttwo=input.nextInt();
System.out.println("======运算结束======");
returnone/two;
}
}
补充说明
当throws抛出的异常类型为非检查型异常时,调用者可以不处理(编译可以通过),但是通常会处理该异常
当throws抛出的异常类型为检查型异常时,调用者必须处理该异常(编译无法通过)
当throws抛出的异常类型为Exception时,调用者必须处理该异常(Exception是检查异常的父类,编译无法通过)
第五节:throw
方案一
publicclassDemo{
publicstaticvoidmain(String[]args) {
test();
}
publicstaticvoidtest() {
Scannerinput=newScanner(System.in);
System.out.println("请输入年龄");
try{
intage=input.nextInt();
if(age<18) {
thrownewException("未到法定年龄");
}else{
System.out.println("欢迎学车");
}
}catch(Exceptione) {
e.printStackTrace();
}
}
}
补充说明
自己抛出的异常自己处理
throw抛出的是异常对象,异常对象中通常包含异常类型,异常出现时的程序运行时的状态等信息
使用异常对象的构造方法打印异常信息
throw抛出的只能是Throwable或其子类的实例对象
方案二
publicclassDemo{
publicstaticvoidmain(String[]args) {
try{
test();
}catch(Exceptione) {
e.printStackTrace();
}
}
publicstaticvoidtest()throwsException{
Scannerinput=newScanner(System.in);
System.out.println("请输入年龄");
intage=input.nextInt();
if(age<18) {
thrownewException("未到法定年龄");
}else{
System.out.println("欢迎学车");
}
}
}
补充说明
在throw抛出异常对象的方法声明处通过throws关键字声明异常类型,由调用者处理异常(调用者可以捕获处理或者继续往上抛)
throws关键字声明的异常类型只能是被抛出异常对象的类型或其父类类型
throw若抛出的异常对象为非检查异常对象,调用者可以不做任何处理,其它情况下必须处理
throw通常抛出的是未检查异常对象
第六节:自定义异常
第七节:异常链