您的位置:首页 > 编程语言 > Java开发

彻底掌握JAVA的异常处理

2013-04-17 16:14 176 查看
异常:阻止当前方法或作用域继续执行的问题。特别需要注意的,程序抛出异常,不管这个异常是否严重,都必须进行处理,决不能有运算结果不出错就是正常的想法。

先来看看异常有哪些类:

Throwable类是JAVA中所有父类,其下有两个子类:Exception与Error

Error:是指不应该试图捕获的严重问题,是不可恢复的错误,比如内存溢出或虚拟机崩溃。

Exception:合理应用程序需要捕抓的条件,Exception包括了CheckException以及RuntimeException,CheckException是指需要在程序中显性指明需要捕抓的异常,而RuntimeException则是可以在程序中不需要显性声明的异常,当发生错误时,直接抛出就是。

其类图关系如下:



先来看看Throwable类的代码,首先Throwable类继承自Serializable接口,表示可以进行序列化为对象,这有利于在网络上传输。

其中,有一个属性定义为Transient,如下:

private transient Object backtrace;

表示该属性是透明的,不需要序列化为对象的。

private StackTraceElement[] stackTrace;//描述异常轨迹的数组

StackTraceElement是一个堆栈描述类,包括了方法名、类名、文件名、行号,用于描述堆栈信息。

fillInStackTrace()是一个声明为native的函数,从调用的位置起记录新堆栈。

public String getMessage() {
return detailMessage;
}
public String getLocalizedMessage() {
return getMessage();
}

getMessage与getLocalizedMessage实际上返回的信息是一样的,如果要加入本地化信息,需要自己在子类中重写。

getCause():获取异常的起因对象,是异常链的一部分

initCause():初始化异常原因

toString():格式化异常信息

printStackTrace():打印堆栈跟踪

getOurStackTrace()获取当前堆栈信息

private native intgetStackTraceDepth();获取当前堆栈信息的深度,0表示堆栈不可用

private native StackTraceElement getStackTraceElement(int index);根据索引获取某个堆栈对象

再看看Exception类与Error类、RuntimeException:

方法基本都是继承自Throwable的,即使是构造函数也是调用父类的进行初始化

异常处理需要注意的地方:

(1) 所有的catch都用Exception 或Throwable来捕抓

try{
//dothong
}
catch(Exception e){
e.printStackTrace();
}

这样捕抓异常,虽然程序不会出错,但程序员无法知道异常的类型,并对其作分别处理,所以,异常必须尽可能捕抓且分开处理,这样才能提高程序的健壮性。

(2)接口污染

public interface aaa{

void readData() throws SQLException;

}

public class StudyInfoimplements aaa {

@Override

public void readData() throws SQLException {

try{

//do something

}

catch(SQLException e)

{

e.printStackTrace();

throw e;

}

}

}

可以看出,以上的接口污染,导致了以后所有继承该接口的类都要抛出SQLException异常,即使没有SQLException也要造一个出来。代码完全可以写成抛出RunTimeException,代码如下:

public interface aaa{

void readData();

}

public class StudyInfoimplements aaa {

@Override

public void readData(){

try{

//do something

}

catch(SQLException e)

{

throw new RuntimeException(e);

}

}

}

这样修改后,程序就变得灵活了很多。

(3) 所有的异常都比较消耗性能,捕获异常时,必须进行处理,否则异常会一层一层向外抛,直到Object对象为止。

(4)throw与throws是有区别的,throws 关键字通常被应用于声明方法时,用来指定可能抛出的异常,多个异常可以用逗号隔开。而throw关键字是抛出某个具体的对象

再提一个执行顺序的问题来加深对Exception的理解:

try{}里有一个return语句,那么紧跟在这个try之后的finally{}里的代码会不会执行,什么时候执行?是在return前还是return后?

答案:会执行,而且在return之后执行,即使是被throw出去后也会执行

因此可以看出,程序执行return时,函数并不会真正返回,只是把返回结果放到函数栈中,等finally语句执行后才真正返回。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: