Java异常机制
1.为什么要使用异常机制
-
没有异常机制的两个坏处
-
逻辑代码和错误处理代码放在一起
-
程序员本身需要考虑的例外情况比较复杂,对程序员本身要求比较高
-
-
常见的异常
-
用户输入错误
-
设备错误
-
硬件问题,比如打印机关掉,服务器问题
-
磁盘满了
-
2.异常(Exception)的概念
- 异常时Java提供的用于处理程序中错误的一种机制
public static void mian(String[] args){
int i = 1/0;
}
Exception in thread "main" java.lang.ArithmetiException: / by zero
at lorinda.matrix.main(matrix.java:11)
-
Java是采用面向对象的方式来处理异常的.处理过程:
-
抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,停止当前执行路径,并把异常对象提交给JRE
-
捕获异常:JRE得到该异常后,寻找相应的代码来处理该异常.JRE在方法的调用栈中查找,从生成的异常的方法开始回溯,直到找到相应的异常处理代码为止
-
Throwable
|
----------
| |
Error Exception
/ / \
/ / \
Unchecked Checked RuntimeException
Exception Exception |
|
Unchecked
Exception
3.Error
-
Error类层次描述了Java运行时系统内部错误和资源耗尽错误.这类错误是我们无法控制的,同时也是非常罕见的错误.所以在编程中,不去处理这类错误.
-
Error表面系统JVM已经处于不可恢复的崩溃状态中
-
打开JDK包:java.lang.error \查看他的所有子类
-
注:我们不需要管理Error
4.Exception
-
所有异常类的父类,其子类对应了各种各样可能出现的异常事件
-
Runtime Exception(unchecked Exception)
-
一类特殊的异常,如被0除,数组下标超范围,其产生比较频繁,处理麻烦,如果显式的声明或捕获将会对程序可读性和运行效率影响很大.因此由系统自动检测并将它们交给缺省的异常处理程序(用户可不比对其处理)
-
常见的Runtime Exception:
ArithmeticException/NullPointerException/ClassCastException/ArrayIndexOutBoundsException/NumberFormatException
-
-
Checked Exception
- 这一类异常,我们必须捕获进行处理
5.try..catch..finally
-
try块
-
一个try语句必须带有至少一个catch语句块或一个finally语句块
-
注:当异常处理的代码执行结束后,不会返回到try语句去执行尚未执行的代码
-
-
catch
-
每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象
-
常用方法:
toString()方法:显示异常的类名和产生异常的原因
getMessage()方法:只显示产生异常的原因,但不显示类名
printStackTrace()方法:用来跟踪异常事件发生时堆栈的内容
-
catch捕获异常时的捕获顺序:
如果异常类之间有继承关系,在顺序安排上需要注意
,越是顶层的类,越放在下面.再不然就直接把多余的catch省略掉
-
-
finally
有些语句,不管是否发生了异常,都必须执行,那么久可以把这样的语句放到finally语句块中
通常在finally中关闭程序已打开的资源,比如:文件流,释放数据库连接等
6.try,catch,finally,return执行顺序
-
执行顺序:
-
执行try,catch,给返回值赋值
-
执行finally
-
return
-
一般不用在finally中使用return
7.声明异常:throws子句
-
当Checked Exception产生时,不一定立刻处理它,可以再把异常throws出去
-
如果一个方法抛出多个已检查异常,就必须在方法的首部列出所有的异常,之间以逗号分隔
8.方法重写中声明异常原则
-
子类声明的异常范围不能超过父类声明的范围
-
父类没有声明异常,子类也不能
-
不可抛出原有方法抛出异常类的父类或上层类
-
9.手动抛出异常:throw子句
-
Java异常类对象在程序执行过程中出现异常时由系统自动生成并抛出,也可以根据需要手动创建并抛出
-
在捕获一个异常前,必须有一段代码先生成异常对象并把它抛出.这个过程我们可以手动做,也可以由JRE来实现,但是他们调用的都是throw子句
-
对于一个已经存在异常的类,抛出该类异常对象过程如下:
-
找到一个合适的异常类
-
创建一个该类的对象
-
将对象抛出
-
10.自定义异常
-
在程序中,可能会遇到任何标准异常类都没有充分描述清楚的问题,这种情况下可以创建自己的异常类
-
从Exception类或者它的其他的子类派生一个子类即可
-
习惯上,定义的类应该包含2个构造器:一个是默认构造器,另一个是带有详细信息的构造器
11.使用异常机制建议
-
要避免使用异常处理代替错误处理,这样会降低程序的清晰性,并且效率低下
-
处理异常不可以代替简单测试---只在异常情况下使用异常机制
-
不要进行小粒度的异常处理---应该将整个任务包装在一个try语句块中
-
异常往往在高层处理