传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229
1异常抛出与捕捉规则
1.1任何抛出异常的方法必须先声明异常
{ // Constructor public MyClass( String name ) throws NullPointerException, llegalArgumentException { ... } }
1.2异常声明后,调用异常对象的构造器抛出异常
public MyClass( String name ) throws NullPointerException, IllegalArgumentException { if ( name == null ) throw new NullPointerException( ); if ( name.length == 0 ) throw new IllegalArgumentException( ); ... }Java异常都从Throwable类继承而来。
1.3用try,catch声明捕捉异常
try { MyClass newobj = new MyClass( name ); } catch ( NullPointerException e ) { // Do something about it } catch ( IllegalArgumentException e ) { // Do something about it }当try中的语句产生异常时,在异常处理函数捕捉了该异常而又没有重新抛出异常时,则在执行完处理函数后,将跳出发生异常的try块,接着执行下面的语句。当try中的语句产生异常时,在异常处理函数捕捉了该异常而又重新抛出异常时,则将把异常抛出到上一层,发生异常的语句之后的代码将不执行。如果没处理相应异常的处理函数,将把异常抛出到上一层,发生异常的语句之后的代码将不执行。如果想捕捉所有异常,只要捕捉Exception异常就行。如果某段代码不管是否发生异常都要执行,那可把它放入finally块中,以finally进行清理。
2取得异常信息的几个常用方法
String getMessage()、getLocalizedMessage 、toString()取得异常对象中的信息。void printStackTrace()、Throwable fillStackTrace()。printStackTrace打印出Throwable和其call stack trace;FillStackTrace则在调用点设立新的stack trace信息。
RuntimeException异常。RuntimeException及其子类所代表的异常我们在程序中不用进行捕捉,如果发生此类异常,Java会自动抛出相应的异常对象。
3继承中异常规则
3.1构造函数中的异常规则
某个derived class构造函数的“异常规格接口”可以比其所调用的父类的构造函数的异常规格接口宽,但决不能变窄。derived class的构造函数必须在自己的异常规格中声明所有base class构造函数的异常规格中所声明的异常。
在derived class的构造函数的异常规格中还可以声明新的异常,即声明在base class构造函数的异常规格中没有声明的异常。
3.2非构造函数的异常规则
某个函数的“异常规格接口”在继承和重载中可以变窄,但决不能变宽。要覆写base class的函数时,如果被覆写函数(base class中的函数)的异常规格中声明了异常,那么覆写函数(derived class中覆写了base class中的函数的那个函数)的异常规格中可以声明:与被覆写函数完全相同的异常;
被覆写函数异常规格中的部分异常或其子类异常;
不声明异常规格。
3.3.产生对象的异常规则
在产生一个对象时,捕捉的是产生对象时所调用的构造函数中所声明的异常。3.4.函数调用时的异常规则
当把一个对象向上转型为它的base class时,并通过转型后的reference进行函数调用时,我们要捕捉的是其base class的异常声明。当用对象的原始类型来调用函数时,只需捕捉所调用的覆写函数的异常。
4异常分类
4.1.Checked Exception
Checked Exception是指那些需要程序显式的处理(捕获或者继续抛出)的异常。在项目中Checked Exception主要可以分为以下三种:4.1.1BizException
项目自己定义的业务异常,BizException下继承了若干个子异常。也就是说BizException是所有项目自定义异常的根类。4.1.2RollbackableBizException
项目自己定义的业务异常,是BizException的子类。4.1.3Other Checked Exception
其他非本项目定义的Checked Exception类异常4.2.Unchecked Exception
Unchecked Exception是指那些不需要程序进行显式处理(捕获或继续抛出)的异常,如果程序需要处理这类异常则其处理方式和Checked Exception一样。在项目中Unchecked Exception 主要可以分为以下两类:4.2.1DataAccessException
这类异常主要是Spring框架定义的数据访问类异常,其具体类型根据数据库的不同和数据库所产生的错误的不同而不同。该类异常描述了数据库访问过程中所产生的错误。其下还有若干个子类异常,下面列出了这些异常:CleanupFailureDataAccessException:数据访问操作之后无法正常执行清除工作,比如JDBC访问之后无法正常关闭Connection。
ConcurrencyFailureException:并发时可能出现此类异常,其下有若干子类异常来标识乐观锁和获取锁失败这两类异常信息。
OptimisticLockingFailureException:在违反了乐观锁机制的情况下会抛此异常
PessimisticLockingFailureException:违反悲观锁机制的情况下会抛出此异常。此异常是由SQLException转换过来的。
CannotAcquireLockException:无法获取锁异常,一般在数据更新时获取锁失败时抛出
DeadlockLoserDataAccessException:当一个并发进程进入死锁链,通常需要抛出异常并回滚该进程产生的事务 。
DataAccessResourceFailureException:当访问某个资源失败时抛出此类异常,比如无法用JDBC与数据库之间建立连接。其下有如下几个子类
CannotCreateRecordException:由于连接器(Connector)内部原因造成创建CC I(Common Client Interface)记录失败时抛出此异常。
CannotGetCciConnectionException:严重异常,无法通过CCI(Common Client Interface)连接EIS(企业信息系统)抛出此异常。
CannotGetJdbcConnectionException:严重异常,无法通过JDBC连接到关系数据库(RDBMS)。
DataIntegrityViolationException:当向数据库插入一条数据或修改数据库中的数据时违反了数据库的完整性约束时抛出此异常。
DataRetrievalFailureException:当无法获取预想的数据时抛出此异常。其下有若干子异常。
IncorrectResultSizeDataAccessException:当获取的数据数量不是预想的数量的时候抛出此异常,比如预想获取到1条数据,但是获得了0条或者多条数据时抛出此异常
LobRetrievalFailureException:LOB无法被获取的时候抛出此类异常
ObjectRetrievalFailureException:通过映射对象(Object)的标识符来获取映射对象失败。
HibernateObjectRetrievalFailureException:将Hibernate和 UnresolvableObjectException, ObjectNotFoundException, ObjectDeletedException和WrongClassException转换为此异常。
InvalidDataAccessApiUsageException:当错误的使用了API的时候抛出此异常
InvalidDataAccessResourceUsageException:当恰当的访问数据时出现此异常,比如,SQL语法不正确。其下有多个子异常类。
BadSqlGrammarException:定义的SQL语句是非法的,有语法错误的时候抛出此异常,一般情况下都是由一个SQLException引起的。
CciOperationNotSupportedException:当连接器(Connector)不支持特定的CCI(Common Client Interface)操作的时候抛出此异常
HibernateQueryException:当HQL(Hibernate的数据库查询语句)语句出现错误时抛出此异常。
IncorrectUpdateSemanticsDataAccessException:当更新数据库数据时出现非预想的结果,这个时候数据库的事务还没有回滚。比如预想修改1条数据,但实际修改了3条数据。
InvalidResultSetAccessException:访问结果集不合法,比如非法的字段名等等。
RecordTypeNotSupportedException:当由于连接器(Connector)不支持预想的CCI记录(record)类型而造成创建一个CCI 记录(record)的失败的时候抛出此异常。
TypeMismatchDataAccessException:当Java类型与数据库(RDBMS)的类型不匹配的时候出现此异常。
UncategorizedDataAccessException:无法分类的异常,其下有若干子异常
HibernateJdbcException:此异常是对Hibernate的JDBC异常的简单包装。
HibernateSystemException:当发生其他一些Hibernate错误是否抛出此异常,这些错误与org.springframework.dao中所定义的异常无法匹配
SQLWarningException、UncategorizedSQLException:无法分类的SQLException
4.2.2Other RuntimeException
其他类型的RuntimeException,例如:NullPointException等。5异常使用原则
使用异常主要是为了报告系统运行中出现的非正常情况。目前异常使用的方法有两种。一种是使用不同的异常类来表示不同的异常,这些异常类的类名就表达了系统所处的非正常状态。另一种是系统中出现的所有异常都用很少的几个异常类来表示,通过这些异常类中Message来表达具体的异常信息。项目主要使用的的是后一种方法。但在某些主要的子系统或与外系统交互时也会采用一些第一种方法。Message主要由两部分组成Key和Param[],其中key的命名规则为:级别(1位)_模块名(可选)_逻辑名,其中级别主要分为Warn(W)和Error(E)两个级别。模块名:指应用功能的名称。逻辑名:从某种角度上来说可以理解为异常的编码。Param[]是具体的异常信息的参数。其具体使用方法如下,首先应用程序从异常中获取Message,然后从Message中获取key值,根据key值从resource文件中获得异常描述信息,将Param[]通过填空形式放入获得异常描述信息中形成一个完整的异常描述信息。
5.1Checked Exception
根据是否需要事务作RollBack操作而使用不同类型的异常。5.1.1RollbackableBizException
需要事务RollBack则抛出RollbackableBizException。5.1.2BizException
如果不需要事务作RollBack操作则抛出BizException。5.1.3Other Checked Exception
在项目的应用程序中只负责处理这类异常,不产生或使用这类异常。5.2Unchecked Exception
鼓励应用程序重用一些通用的UncheckedException异常,如IllegalArgumentsException, NullPointException等。5.2.1DataAccessException
大多数情况下这类异常应用程序不用关心,特别是DAO类的对象不用关心这类异常。它是Spring框架所抛出的数据库访问的异常。5.2.2Other RuntimeException
6异常处理原则
异常处理需要遵循几点基础原则:第一,能处理则进行处理和关心的异常,不能处理或不关心的异常则继续抛出。决不允许出现捕获异常但又不做任何处理或抛出操作,这样会丢失异常信息。
第二,异常抛出源需要在抛出异常之前将异常写入日志中。以备进行检查。
应用程序所处层次的不同其对异常的处理也有所差别。下面列出了每个层次的应用程序在处理异常的一些原则。
下图是项目中异常使用的一个图释: