Java异常处理

[b]一、异常简介[/b]
在程序运行过程中,如果环境检测出一个不可以执行的操作,就会出现运行时错误。如果这个错误没有被处理,那么程序将会非正常终止。该如何处理这个异常,以使程序可以继续运行或者平稳终止呢?这就是下面要说到的异常处理。

警告:在这里有必要声明一下,异常处理需要初始化新的异常对象,需要从调用栈返回,而且还需要沿着方法调用链来传播异常以便找到它的异常处理器。所以,异常只有当必须处理不可预料的错误状况时我们才能使用它,不要用try-catch块处理简单的、可预料的情况。比如空指针这些都应该用if来代替。

[b]二、异常类型[/b]
下面是Java1.6 API对异常类型的部分截图:
[img]http://dl2.iteye.com/upload/attachment/0096/5188/31e553ff-9c61-3347-bf82-9de03ead410c.jpg[/img]
其中,RuntimeException类、Error类以及它们的子类都称为免检异常,所有其它异常都称为必检异常,意思是指编译器会强制程序员检查并处理它们。为避免过多地使用try-catch块,Java语言不允许编写代码捕获或声明免检异常。

1. Throwable类是所有异常类的根。所有的Java异常类都直接或者间接地继承自Throwable。

2. Error类扩展了Throwable类,描述的是内部系统错误,由Java虚拟机抛出,如果发生,除了通知用户以及尽量稳妥地终止程序外,几乎什么也不能做。

3. Exception类也扩展了Throwable类,它描述的是由程序和外部环境所引起的错误,这些错误能被程序捕获和处理。

4. RunTimeException类是Exception类的一个扩展,它描述的是程序设计错误,例如错误的类型转换,数组越界等。运行时异常通常由Java虚拟机抛出。

[b]三、异常处理[/b]
[b]1. 声明异常[/b]
程序中每个方法都必须声明它可能抛出的必检异常的类型,方法的调用者就必须去捕获该异常,这称为声明异常。语法如下:
public void myMethod() throws Exception1,Exception2{ ... }
如果方法抛出的是免检异常(Error异常和运行时异常)调用者也不会被编译器强制try/catch异常。如果方法在父类中没有声明异常,那么就不能在子类中对其进行覆盖来声明异常。

[b]2. 抛出异常[/b]
检测一个错误的程序可以创建一个正确异常类型的实例并抛出它,这时catch()块将接手这个异常。这就称为抛出一个异常。通常,Java API中的每个异常类至少有两个构造方法,一个无参构造方法和一个带有可描述这个异常的String参数的构造方法,如下:
throw new Exception1();
throw new Exception1("message");

[b]3. 捕获异常[/b]
当抛出一个异常时,可以在try-catch块中捕获并处理它,如下:
try{
...
}catch(Exception1 e1){
...
}catch(Exception2 e2){
...
}
从第一个到最后一个逐个检查catch块,判断在catch块中的异常类实例是否是该异常对象的类型。如果是,就将该异常对象赋值给所声明的变量,然后执行catch块中代码。如果没有发现异常处理器,Java会退出这个方法,把异常传递给调用这个方法的方法,继续同样的过程来查找处理器。如果在调用的过程中找不到处理器,程序就会终止并且在控制台上打印出错信息。
如果一个catch块可以捕获一个父类的异常对象,它就能捕获那个父类的所有子类的异常对象。注意,如果父类的catch块出现在子类的catch块之前就会导致编译出错。

[b]4. 获取异常信息[/b]
Throwable类中提供了一些方法来获取异常对象的有价值的信息,如下:
public String getMessage() //返回这个对象的消息
public String toString() //返回异常类的命名+":"+getMessage()
public void printStackTrace() //在控制台打印Throwable对象以及它的调用栈的跟踪信息
public StackTraceElement[] getStackTrace() //返回栈跟踪构成的数组来表示这个可抛出的栈跟踪信息

[b]5. finally子句[/b]
有时候无论异常中否出现或者中否被捕获,都希望执行某些代码,可利用finally子句来达到这个目的。
try{
...
}catch(Exception1 e1){
...
}finally{
...
}
注意,即使在到达finally块之前有一个return语句,finally块还是会执行。

[b]6. 重新抛出异常[/b]
如果异常处理器没有处理某异常、或者处理器只是希望它的调用者注意到该异常,Java就允许异常处理器重新抛出该异常,此时调用者的其它处理器就会获得处理此异常的机会。
try{
...
}catch(Exception1 e1){
...
throw e1;
}

[b]7. 链式异常[/b]
有时候,可能需要同原始异常一起抛出一个新异常(带有附加信息),这称为链式异常。
try{
...
}catch(Exception1 e1){
...
throw new Exception1("new exception", e1);
}

[b]8. 创建自定义异常类[/b]
Java提供了相当多的异常类,尽量使用它们不要创建自己的异常类。如果遇到一个不能用预定义异常类恰当描述的问题,那我们就可以通过派生Exception类或其子类来创建自己的异常类。
    public MyException extends Exception{
private String value;
public MyException(String value){
super("Value:" + value);
this.value = value;
}
public String getValue(){
return value;
}
}

throw new MyException("jiang");


提示,我们尽量不要去扩展RentimeException免检异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值