Java异常为我们提供了一致的识别和处理程序错误的机制,有效的异常处理能增强程序的健壮性和易于调试性。

首先还是重温下java的异常体系结构,如图所示,所有异常的根是Throwable,异常又分为checked exceptionunchecked exceptionRuntimeException就是属于unchecked exceptionJVM 一旦捕捉到unchecked exception 就会终止当前运行的程序,并在console中打出错误信息。

 

Java exception hierarchyption hierarchy

一、Unchecked exceptions VS Checked exceptions

 下表列出使用两种异常的场合:

Client's reaction when exception happens

Exception type

Client code cannot do anything

Make it an unchecked exception

Client code will take some useful recovery action based on information in exception

Make it a checked exception

 这个方面的例子hibernate就是一个,在hibernate2中,HibernateException还是checked exceptions,但是到了hibernate3中就成了unchecked exceptions,因为对于数据库操作来说,一旦出现异常,就是比较严重的错误,而且在client端基本上是无能为力的,使用unchecked exceptions更加合适。

另外,unchecked exceptions的优点在于不强迫客户端代码显式地处理他们,异常可以一直往上传递(除非需要转化异常,否则异常不需要在中间被捕捉,节省了很多的try{}catch(),代码更加简洁),直到你想捕捉处理他们,(有人会问,如何不强制客户端处理他们,比如像checked exceptions这样,不处理就是语法错误,如何保证异常能够得到处理呢?在这点上,java提供的完善的文档机制,通过API客户端程序员可以很方便地知道他调用的方法可能会抛出什么异常,一个负责人的程序员就应该对其进行catch和处理),Java API提供了很多的unchecked exceptions,比如NullPointerException, IllegalArgumentException, and IllegalStateException,使用java提供的标准的unchecked exceptions是值得推荐的,这样的好处在于使代码更加简洁并可以减少代码对内存的占用。

二、Java异常的推迟处理

Java异常应该尽可能地推迟处理,除非要转化异常,重新抛出,否则最好不要处理,而是留给最后能够处理异常的地方。

通过为方法添加throws声明,可以将处理异常的责任传递到更高的层次。在声明哪些需要抛出的时候,应该尽可能地详细。这样做的目的是可以在API中详细地表述出该方法可能会出现的异常,从而让调用该方法的clinet程序员做好处理异常的准备,比如对于代码通过throws语句详细地声明了可能会抛出的异常,这样调用该方法的程序员就会知道将会有什么样的异常会发生。

public void readPreferences(String filename)

    
throws IllegalArgumentException,

          FileNotFoundException, IOException
{

    
if (filename == null)
    {

        
throw new IllegalArgumentException

                        (
"filename is null");

    }  
//if
    
//
    InputStream in = new FileInputStream(filename);

    
//
}

从语法上讲,IllegalArgumentExceptionunckecked exception 是不需要声明的,但是为了从文档的角度考虑,最好还是加上,这样可以让调用这个方法的程序员知道,这个方法会可能抛出该异常,需要加以捕捉和处理。

 

三、异常的处理

不管如何,最终程序肯定是要对异常进行处理的,否则会导致不确定情况的发生,但是选择异常处理的位置却是有技巧的,通常要么是程序在这些地方从异常中恢复、继续执行且不会导致进一步异常的发生,要么是在这些地方能为用户反馈特定的信息,比如,如何避免异常的发生或者如何从异常中恢复。因此,对于有用户界面层的程序,将异常的捕捉和处理推迟到UI层是有好处的,在UI层可以使用对话框或者其他方式提示用户出现异常。
 

参考文献

Best Practices for Exception Handling by Gunjan Doshi

Three Rules for Effective Exception Handling by Jim Cushing