1.异常的定义
在java中,阻止当前方法和作用域的情况,称之为异常。异常是程序中的一些错误,但不是所有错误都是异常。
异常的原因通常是以下几种:
(1)用户输入了非法数据
(2)要打开的文件不存在
(3)网络通信时连接中断,或者jvm内存溢出
这些异常可能是用户错误、程序错误、物理错误引起的。
理解java异常处理是如何工作的,需要掌握三种类型的异常。
编译期异常:最具代表性的检查性异常是用户错误或问题引起的异常。程序员无法预见,例如要打开一个文件,文件不存在,异 常发生,这些异常在编译时,不能被简单的忽略。
运行时异常:运行时异常可以被预见,与编译期异常相反,运行时异常可以在编译期被忽略。
错误:错误脱离程序员控制,错误在代码中通常被忽略。例如:当栈溢出时,错误就发生了,在编译期检查不到。
1.1异常分类
1.1.1运行期异常
由系统检测,用户的java程序可以不做处理,系统将他们交给缺省的异常处理程序。
1.1.2编译期异常
在程序中必须对其进行处理,否则编译器会指出错误。
2.异常的继承结构
Java的所有不正常类都属于Throwable类。Throwable主要包括两大类:一个是Error类,另一个是Exception类。
其中Error类中包括虚拟机错误或线程死锁。Error一旦出现,程序直接挂掉,被称为程序终结者。
Exception,也就是通常所说的异常,主要指编码、环境、用户操作出现问题。Exception主要包括两大类:非检查异常(RuntimeException)和检查异常(其他异常)。
RuntimeException主要包括一下四中异常:空指针异常、数组下标越界异常、类型转换异常、算数异常。RuntimeException异常会由java虚拟机自动抛出并且自动捕获。
3.异常的处理机制
Java中处理异常有两种方式:捕获异常、声明抛出异常。捕获异常,就地解决 。并使程序继续执行。声明抛出异常就是讲异常向外转移,即将异常抛出方法之外。由调用该方法的环境去处理。
3.1异常的捕获
3.1.1 try...catch...finally代码块
try{
//一些会抛出的异常
}catch(Exception e){
//第一个catch
//处理该异常的代码块
}catch(Exception e){
//第二个catch,可以有多个catch
//处理该异常的代码块
}finally{
//最终要执行的代码
}
(1)try代码块
捕获异常的第一步是用try{...}选定捕获异常的范围,try模块中的语句时程序正常流程里要执行的语句,但是在执行过程中可能出现异常。所有可能抛出异常的语句都放入try模块中。
(2)catch(必有)代码块
每个try代码块可以伴随一个或多个catch语句,用于处理try代码块中所生成的异常事件。catch语句只需要一个形式参数指明它所能够捕获的异常类型,这个类必须是Throwable的子类,运行时系统通过参数值把被抛弃的异常对象传递给catch块,在catch中,是对异常对象进行处理的代码,与访问其他对象一样,可以访问一个异常对象的数据成员或调用他的方法。
getMessage()是类Throwable所提供的方法,用来得到有关异常事件的信息。
类Throwable还提供了方法printStackTrace()用来跟踪异常事件发生执行堆栈的内容。
catch语句块中异常捕获的顺序:
捕获异常的顺序和catch语句的顺序有关,当捕获到一个异常时,剩下的catch语句就不再匹配。因此,在安排catch语句的顺序时,首先应该捕获最特殊的异常,然后再逐渐一般化。也就是先安排子类,再安排父类。
(3)finally(可选)
捕获异常的最后一步是通过finally语句为异常处理提供一个统一的出口。不论资try语句块中是否发生了异常时间,finally语句块都会被执行。try语句块和finally语句块中的return哪个先执行?
finally关键字用来创建在try代码块后面执行的代码块。
无论是否发生异常,finally代码块中的代码总会被执行。
在finally代码块中,可以运行清理类型等收尾善后性质的语句。
3.1.2 异常的捕获示例演示
try{
Thread.sleep(1000);
Field field = People.class.getDeclaredField("name");
}catch(InterruptedException e){
e.printStackTrace();
}catch(NoSuchFiledException e){
e.printStackTrace();
}finally{
System.out.println("必定会被执行");
}
3.1.3异常捕获时注意事项
catch不能独立于try存在
在try/catch后面添加finally块并非强制要求。
try后面不能既没有catch,也没有finally。
try,catch,finally块之间不能添加任何代码。
3.2抛异常
在java程序的执行过程中,如果出现了异常事件,就会出现一个异常对象。生成的异常对象将传递给Java运行时系统。这一异常的产生和提交过程称为抛出异常。
3.2.1throws/throw关键字
如果一个方法没有捕获到一个检测性异常,那么该方法必须使用throws关键字来声明。throws放在方法签名的尾部。也可以使用throw关键字抛出异常。
一个方法 可以声明抛出多个异常,多个异常之间用逗号隔开。
一个方法不处理它所产生的异常而是沿着调用层次依次往上传递,由调用的他的这些方法处理这些异常。叫声明抛出异常。
是一种消极的异常处理机制。
抛出异常就是产生异常对象的过程。首先要生成异常对象,异常或者由虚拟机产生,或者由某些类的实例生成。也可以在程序中生成。在方法中,抛出异常对象是由Throw语句实现的。
可以抛出的异常必须是Throwable或其子类的实例。
用户定义的异常同样用try-catch捕获,但必须由用户自己抛出throw new Exception()。
4.用户自定义异常
在java中可以自定义异常。
(1)所有异常都必须是Throwable的子类。
(2)如果需要编译期异常类,需要继承Exception类。
(3)如果写一个运行时异常类,需要继承RuntimeException类。