异常处理—三种:
1. 在出现异常的方法内捕获并处理异常,该方法的调用者将不能再次捕获该异常。(catch)
2. 该方法签名中声明抛出该异常,将该异常完全交给方法调用者处理。(throw)
3.出现异常的当前方法和该方法的调用者都要处理。(catch中加throw)
catch和throw结合是在企业级应用对异常处理很常用,主要有两个部分:
1.应用后台需要通过日志来记录异常发生的详细情况,
2.应用还需要根据异常想应用使用者传递某种提示。
异常链:
企业应用中,常有严格的分层,如下图
当业务逻辑层访问持久层出现SQLException异常时,程序不应该把底层的SQLException异常传递到用户界面,原因是:
1. 对于用户而言,他们不理解SQLException,不友好
2. 对于恶意用户而言,SQLException暴露出来是不安全的。
所以把底层的原始异常传给用户是很不好的,通常情况下,程序先捕获原始异常,然后抛出一个新的业务异常,新的业务异常包含了对用户的提示信息,这叫做异常转译。
这种把捕获一个异常然后接着抛出一个异常,并把原始异常信息保存下来是一种典型的链式处理—职责连模式,也称为“异常链”;
一,持久层的异常处理
/* *throw和catch结合处理异常 */ public void delFlowCardDetail(String[] flowCardVouNos) throws DaoException {//throws声明抛出的异常,因为方法中显式的抛出了这个异常,所以这里需要声明下 StringBuffer sbStr = new StringBuffer(); String sql = "delete from t_flow_card_detail where flow_card_no in (" + sbStr.toString() + ")"; PreparedStatement pstmt = null; try {//try块,把可能出现异常的代码放到这里 Connection conn = ConnectionManager.getConnection(); pstmt = conn.prepareStatement(sql); for (int i=0; i<flowCardVouNos.length; i++) { pstmt.setString(i+1, flowCardVouNos[i]); } pstmt.executeUpdate(); }catch(SQLException e) {//捕获SQLException异常 //打印异常跟踪信息 e.printStackTrace(); //抛出自定义异常 throw new DaoException(e); }finally { //释放物理资源 ConnectionManager.close(pstmt); } }
二,业务逻辑层异常处理
public void delFlowCardDetail(String[] flowCardVouNos) throws ApplicationException { try { flowCardDao.delFlowCardDetail(flowCardVouNos); }catch(DaoException e) {//捕获DaoException //抛出新的业务逻辑异常,提示“删除失败” throw new ApplicationException("删除流向单失败!"); } }
自定义的异常类
public class DaoException extends RuntimeException { //无参数的构造函数 public DaoException() { } //message:异常详细信息传递给,异常对象的message属性 public DaoException(String message) { super(message); } //cause:异常类,用它来封装原始异常,从而实现,对异常的链式处理。 public DaoException(Throwable cause) { super(cause); } //异常信息和异常类 public DaoException(String message, Throwable cause) { super(message, cause); } }
Java的异常跟踪栈
异常对象的printStackTrace方法用于打印异常的跟踪栈信息,根据printstackTrace方法输出结果,我们可以找到异常的源头,并可以看到异常一路触发的过程。
异常处理规则:
使程序代码混乱最小化,捕捉并保留诊断信息,通知合适人员,采用合适的方式结束异常活动。
不要过度使用异常处理,滥用会造成:
1. 把异常和普通错误混淆在一起不再编写任何错误处理代码,而是以简单地抛出异常来代替所有错误处理
2. 使用异常处理来代替流程控制。
不要使用过于庞大的try块,把大的try块分割成多个可能出现异常的程序段落,并把他们放在单独的try块中,从而分别捕获并处理异常。