java异常

原文出处: 代码钢琴家

简介

异常指不期而至的各种状况,如:文件找不到、网络连接失败、非法参数等。异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程。java通过API中的Throwable类的众多子类来描述各种异常,java异常都是对象,是Throwable的子类。

java异常分类和类结构图

从基类Throwable派生出两个类Error和Exception

Error:错误,代表JVM本身的错误,错误不能被程序员通过代码处理,Error一般很少出现。
Exception:异常,代表程序运行时发生的各种不期望发生的时间,可以被java异常处理机制使用,是我们说的异常处理的核心

对异常的处理要求我们将异常分为两类:

非检查异常(unckecked exception):编译器不要求强制处置的异常包括运行时异常(RuntimeException与其子类)和错误(Error)。

检查异常(checked exception):编译器要求必须处置的异常,除了Error 和 RuntimeException的其它异常。javac强制要求程序员为这样的异常做预备处理工作(使用try…catch…finally或者throws)。

异常处理的基本语法

在编写代码处理异常时,对于检查异常,有2种不同的处理方式:使用try…catch…finally语句块处理它。或者,在函数签名中使用throws 声明交给函数调用者caller去解决。

try…catch…finally语句块 “try…catch…finally语句块”

try…catch…finally语句块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
try{  
//try块中放可能发生异常的代码。
//如果执行完try且不发生异常,则接着去执行finally块和finally后面的代码(如果有的话)。
//如果发生异常,则尝试去匹配catch块。

}catch(SQLException SQLexception){
//每一个catch块用于捕获并处理一个特定的异常,或者这异常类型的子类。Java7中可以将多个异常声明在一个catch中。
//catch后面的括号定义了异常类型和异常参数。如果异常与之匹配且是最先匹配到的,则虚拟机将使用这个catch块来处理异常。
//catch块中可以使用这个块的异常参数来获取异常的相关信息。异常参数是这个catch块中的局部变量,其它块不能访问。
//如果当前try块中发生的异常在后续的所有catch中都没捕获到,则先去执行finally,然后到这个函数的外部caller中去匹配异常处理器。
//如果try中没有发生异常,则所有的catch块将被忽略。

}catch(Exception exception){
//...
}finally{

//finally块通常是可选的。
//无论异常是否发生,异常是否匹配被处理,finally都会执行。
//一个try至少要有一个catch块,否则, 至少要有1finally块。但是finally不是用来处理异常的,finally不会捕获异常。
//finally主要做一些清理工作,如流的关闭,数据库连接的关闭等。
}

tips:

  • try块和catch块中的局部变量和finally中的局部变量不能共享使用
  • 一个catch块处理一个异常
  • 当发生异常时,java将从异常发生的地方跳转到处理异常的代码,在处理完异常后,回到原来的控制流中去(类似中断?)

throws 函数声明

throws声明:如果一个方法内部的代码会抛出检查异常(checked exception),而方法自己又没有完全处理掉,则javac保证你必须在方法的签名上使用throws关键字声明这些可能抛出的异常,否则编译不通过。

throws是另一种处理异常的方式,它不同于try…catch…finally,throws仅仅是将函数中可能出现的异常向调用者声明,而自己则不具体处理。

finally块

finally块不管异常是否发生,只要对应的try执行了,则它一定也执行。只有一种方法让finally块不执行:System.exit()。因此finally块通常用来做资源释放操作:关闭文件,关闭数据库连接等等。

良好的编程习惯是:在try块中打开资源,在finally块中清理释放这些资源。

需要注意的地方:

1、finally块没有处理异常的能力。处理异常的只能是catch块。

2、在同一try…catch…finally块中 ,如果try中抛出异常,且有匹配的catch块,则先执行catch块,再执行finally块。如果没有catch块匹配,则先执行finally,然后去外面的调用者中寻找合适的catch块。

3、在同一try…catch…finally块中 ,try发生异常,且匹配的catch块中处理异常时也抛出异常,那么后面的finally也会执行:首先执行finally块,然后去外围调用者中寻找合适的catch块。

throw异常抛出语句 “throw异常抛出语句”)

throw异常抛出语句

throw exceptionObject

程序员可以自己手动显式的抛出一个异常,throw语句的后面跟的是一个异常对象,和JRE自动抛出的异常没有区别

1
2
3
4
5
6
public void save(User user)  
{
if(user == null)
throw new IllegalArgumentException("User对象为空");
//......
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!