什么是异常

定义:异常本质上是程序上的错误
错误在我们编写程序的过程中会经常发生,包括编译期间和运行期间的错误。
常见编译错误:括号未正常配对,语句结束后少写了分号,关键字编写错误。
常见运行期间错误:使用空的对象引用调用方法,数组访问时下标越界,算术运算时除数为0,类型转换时无法正常转型
异常:程序运行过程中,意外发生的情况,背离我们程序本身意图的表现,都可以理解为异常。

异常分类

对各种类型异常进行描述
Throwable(根类):

Error 是程序无法处理的错误,表示运行应用程序中较严重的问题

-虚拟机错误VirtualMachineError
-内存溢出OutOfMemoryError
-线程死锁ThreadDeath

Exception是程序本身可以处理的异常。异常处理通常指针对这种类型异常的处理

-检查异常Checked Exception (指编译器要求必须处置)
IO异常IOException
SQL异常SQLException
-非检查异常Unchecked Expection(指编译器不要求强制处置的异常)
RuntimeExpection
空指针异常:NullpointerException
数组下标越界异常:ArrayIndexOutOfBoundsException
算术异常:ArithmeticException
类型转换异常:ClassCastException

异常处理分类

1,异常处理机制分为2大步骤:
1)抛出异常:当一个方法中出现错误引发的异常时,方法会去创建对象,并且交付给运行时系统来进行处理。异常对象包含异常类型和异常出现时的程序状态等信息。
2)捕获异常:当运行时系统捕获到异常时,就会进行到捕获异常环节,在此时运行时系统会去寻找合适的处理器,如果找到了会执行相关处理逻辑,如果没找到程序就会终止,意味着程序就停止了。
2,对于运行时异常,错误或可查异常,java技术所要求的异常处理方式有所不同。
1)对于可查异常必须捕捉或者声明抛出
2)允许忽略不可查的RuntimeException(含子类)和Error(含子类)
通过5个关键字来实现:try,catch,finally,throw,throws,前三个为一组

try-catch-finally简介

1,try块主要用于捕获异常
catch块用于对异常进行处理
finally无论是否发生异常代码总能执行
2,try块后可接0个或者多个catch块,如果没有catch块,则必须跟一个finally块组合使用,不允许单独存在。
3,catch和finally不能单独组合使用

使用try-catch结构处理异常

try 抛出异常
catch 捕获异常
finally 无论catch里执行与否 都会执行finally里的代码

使用多重catch结构处理异常

Exception的子类:
ArithmeticaException,算数异常
InputMismatchException,输入格式异常
1.两个catch块的异常类型不允许相同
2.在多重catch块中,可以在最后一层catch块里用Exception捕捉之前的catch块无法捕捉异常

终止finally执行的方法

System.exit(1)
非0数字,jvm异常终止
因此finally终止执行

return关键字在异常处理中的作用

finally return语句块强制执行 导致try catch 里面return的语句被屏蔽了

使用throws声明异常类型

1.如果一个方法可能会出现异常,但没有能力处理这种异常,可以在方法声明处用throws自子句来声明抛出异常。(右键surround with,try-catch自动处理)
2.throws语句用在方法定义是声明该方法要抛出的异常类型
public void method() throws Exception1,Exception2,...,ExceptionN{ //可能产生异常的代码 }
3.当方法抛出异常列表中的异常时,方法将不对这些类型及其子类类型的异常做处理,而抛向调用该方法的方法,由它去处理
4.通过throws抛出异常时,针对可能出现的多种异常情况,解决方案:

  • throws后面接多个异常类型,中间用逗号分隔
  • throws后面接Exception
    5.在方法中声明抛出Exception异常,在调用方法时就必须处理这个异常

6.检查异常:算数异常
非检查异常:输入格式异常(编译器不会强制要求处理)
若想查看非检查异常,可利用文档注释进行异常提示

使用throw抛出异常对象

throw用来抛出一个异常
例如:throw new IOException();
throw抛出的只能够是可抛出类Trowable或者其子类的实例对象
例如:throw new String("");是错误的
处理throw的常规方案
1.方案一
在throw语句外面套上对应的try,catch块,自己抛自己处理

public void method(){
try{
//代码段1
throw new 异常类型();
}catch(异常类型ex){
//对异常进行处理的代码段2
}
}

2.方案二
也就是通过throws在方法声明中抛出异常类型,谁调用的这个方法,就由谁来处理这个异常

public void methos() throws 异常类型{
//代码段1
throw new 异常类型();
}

throw抛出异常对象的处理方案:
1、通过try..catch包含throw语句--自己抛自己处理
2、通过throws在方法声明出抛出异常类型--谁调用谁处理--调用者可以自己处理,也可以继续上抛
此时可以抛出与throw对象相同的类型或者其父类

异常类型向下兼容;
子类异常必定属于父类异常,反之不然

自定义异常类

使用Java内置的异常类可以描述在编程时出现的大部分异常情况
也可以通过自定义异常描述特定业务产生的异常类型
所谓自定义异常,就是定义一个类,去继承Throwable类或者它的子类

异常链简介

定义:将异常发生的原因一个传一个穿起来,即把底层的异常信息传给上层,这样逐层抛出
1.时候我们会捕获一个异常后再抛出另一个异常(见截图)
2.但是这样做有时会导致前面异常信息的丢失
3.在Java中提供了这种保留异常的机制
代码实现:在testThree的catch块中做如下改动:

catch(Exception e){
Exception e1 = new Exception("我是新产生的异常2");
e1.initCause(e);
//保留之前异常的信息
throw e1;
}

总结

在java应用程序中,异常处理机制为:抛出异常,捕捉异常,通过5个关键字来实现:try,catch,finally,throw,throws.
1,当我们把可能出现异常的代码放入try块中,且无异常信息发生时,catch块的代码不会被执行,只执行后面的代码。
2,但当try块中发生异常,产生异常对象,并且该异常对象类型与catch块类型匹配时,程序先进入catch块的执行环节,然后顺序执行
3,当try块抛出异常和catch块异常类型无法正常匹配时,则程序会中断执行,catch块后面的代码就不会正常执行。
4,如果try块后面代码会产生多种类型的异常,就可以通过多重catch的方式实现不同类型的异常的匹配。
5,我们可以在catch块后面加上finally块来保证某段代码无论是否执行catch块,都能够正常执行。
6,一旦在try块或catch块中加入System.exit(1),finally块将会强制终止执行。
7,当代码出现return,表示finally块已经执行完毕,因为只有finally块执行完后,才会执行return代码,无论return语句放在何处。

最后修改:2019 年 12 月 31 日 11 : 41 PM
如果觉得我的文章对你有用,请随意赞赏