战五渣系列之二(你会处理异常Exception ?)

1.为什么写异常处理?

  • 大多数程序员根本不懂得如何去处理异常。他们总是认为try…catch或者throw就能解决问题。
  • 他们从来就没有想过他的调用者会怎么处理他处理过的这个异常。
  • 我受够了这些api的调用!

2.且看我如何战五渣!

  • 什么是异常?程序不正常运行产生的现象,如:参数不合法、文件未找到。正常运行是不会产生异常的!
  • 异常的分类:checked Exception(编译时异常,必须显示的处理)、unchecked Exception(运行时异常RuntimeException)
  • throw or try…catch ?我们先看看以下这个案例:
失败的处理方式之一:每个调用者都不得不处理,他只能增加调用者的负担,并且该处理显得毫无意义。
//基础Dao层api
public int addEntity(T t)  throws Exception;

//调用者不得不显示的处理这个异常,尽管这种操作毫无意义
public int addUser(User user){
    try{
        return dao.addEntity(user);
    }catch(Exception exception){
        //诸位,想一想你在这个地方能做什么操作 ?
        logger.error("add user error:"+exception...);

    }
    //这个-1难道这比直接抛出异常更有意义?
    return -1;
}
失败的处理方式之二 : 提供调用者根本无法处理的异常。
public int addUser(User user){
    try{
        DaoHelper.sql.beginTranction();//api抛出异常
        //执行语句DaoHelper.sql.insert(.....);//api竟然也抛出异常
        DaoHelper.sql.commitTranction();//api抛出异常
    }catch(SqlException exception){
        try{
            DaoHelper.sql.rollBackTranction();//api抛出异常
        }catch(SqlException exception){
            //我实在不知道该在这个地方怎么处理 !!!
        }
    }finally{
        try{
            DaoHelper.sql.endTranctiuon();//api抛出异常
        }catch(SqlException exception){
            //我实在不知道该在这个地方怎么处理!!!

        }
    }
    //我都不知道返回值怎么写了

}

这是我见过最傻逼的异常处理方式,没有之一。每一个DaoHelper都抛出异常,什么业务都没写,这些代码必不可少,他不但给调用者带来负担,而且给调用者带来困惑:我要做什么?我能做什么?DaoHelper.sql.rollBackTranction()抛出异常如何处理?这是目前一大互联网公司的真实代码!每一个员工的dao层方法必有以上10行代码!

失败的处理方式之三 : 调用者找不到异常发生的地方。
//这个比较少见,在我的职业生涯中也就碰到过那么一次(我在调试时始终找不到正确的地方),但是具有警示意义:那就是如果你不知道如何去处理这个异常,请不要去包装这个异常
public int addUser(User user){
    try{
        userDao.addUser(user);//产生RuntimeException
    }catch(Exception exception){
        throw new Exception("用户插入失败!");//异常本来发生的地方就被埋没了,如果userDao.addUser(user)的异常是层层上抛了三次就更加可悲了!
    }
}
失败的处理方式之四 : 你真的需要自定义异常?
  • 很多同志都说,我们来个自定义异常吧。我实在想不通为什么要这么做?因为在我有限的编程生涯中唯一想到的就是警示业务运行出现错误!如:throw new OrderNotFoundException();这样做比返回null 更有意义吗?throw new BadManException() ?用异常来控制业务流程,你必须一开始就对业务作出技术规划!
  • 难道仅仅是因为你掌握了throw这个关键字,或者你也想这么做:throw new BadCredentialException();

其他的异常处理方式太过简单就不再提起,因为对渣渣程序员来说不会犯那些try..catch 而又毫无动作的错误。

3.重要点

异常处理的关键之处在于:当你决定处理这个异常时,你的调用者会怎么办!

  • 不要在dao中抛出checked Exception,不要在dao中捕获RuntimeException!
  • 不要轻易抛出checked Exception,除非你认为调用者必须处理!
  • 不要在只读操作中轻易抛出RuntimeException 例如:throw new RuntimeException("数据不存在");可以修改为 return null ; 或者 return Collections.emptyList();
  • 如果你认为调用者不能通过try…catch来处理此操作,请务必使用RuntimeException。避免程序必定正常运行的资源被错误的处理了,否则try…catch跑到线上就完蛋了!例如:throw new RuntimeException("jdbc.properties不存在");

一个好的api不但给调用者带来便利,还直接影响着调用者的技术。因为他总是不得不去配合这个api以改变自己的代码,使自己逐渐成为一个合格的渣渣。

4.那么问题来了,上面的第一条总结对Spring的事物会产生影响吗?我们为什么要在业务层控制事物?

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值