Java学习笔记——Java Exception

677 阅读3分钟

导语

经常在项目中碰到各式各样的异常处理方式,各有风格但又较为混乱,对我一个新手程序员照成了很多使用上的困惑和疑虑。
本篇文章基于项目中异常使用和处理进行学习和总结,希望对各位小伙伴有所帮助!

异常的选择

  1. 自定义业务异常包含原始异常(或堆栈信息),方便调用方快速定位问题。
public class BaseException extends RuntimeException {
    public BaseException() {
        super();
    }

    public BaseException(String message, Throwable cause) {
        super(message, cause);
    }

    public BaseException(String message) {
        super(message);
    }

    public BaseException(Throwable cause) {
        super(cause);
    }
}
  1. 合理的异常分层
  • DAO层:SQL异常,数据库连接池异常,MYBATIS异常等;
  • Service层:封装DAO层异常,并加入业务异常;
  • Web 层:对业务异常进行捕获并处理。
  1. 避免直接使用RuntimeException
    使用有业务含义的自定义异常。推荐业界已定义 过的自定义异常,如:DAOException / ServiceException等。

异常处理

捕获异常的处理应当遵循以下原则:

  1. 切勿把异常捕获当作流程控制
    阿里巴巴开发手册所述:异常设计的初衷是解决程序运行中的各种意外情况,且异常的处理效率比条件判断方式 要低很多!
  2. 要么处理要么抛出
    try{
        //可能出现异常代码片段(注:try一大段代码是不负责的行为)
    }catch(SQLException e){//pls deal it
        //1.no means!若你还不知道怎么处理,建议直接抛出,只由最后处理对象打印,尽可能的减少不必要的日志与堆栈信息
        e.printStackTrace()(); //
        log.info(e.getMessage());
        //2.处理逻辑必要保证严谨,若有异常出现可能,必须再捕获处理
        try...catch(){}
        //3.better choose:可以利用非检测异常(unchecked Exception)封装检测异常(checkException),降低层次耦合!
        throw new RuntimeException(SQLErrorCode, e);
    }finally{
        //关闭resultset,statement,connection etc(1.7版本后推荐 try-with-resources)
        //不要在finally使用return
    }
  1. 通知调用方更多的异常相关信息
    尽可能详细通知调用方,在什么情况下会抛出哪种异常(包含返回null情况)
    public interface List<E> extends Collection<E> {
    /**
     * @param o element whose presence in this list is to be tested
     * @return <tt>true</tt> if this list contains the specified element
     * @throws ClassCastException if the type of the specified element
     *         is incompatible with this list
     * (<a href="Collection.html#optional-restrictions">optional</a>)
     * @throws NullPointerException if the specified element is null and this
     *         list does not permit null elements
     */
    boolean contains(Object o);
  1. 最终调用方必须处理和打印异常
    可利用框架aop->SpringMVC统一异常处理,将异常的处理织入到框架的最外层进行处理,这样的好处不言而喻,你不需要到处try...catch,更加的简洁清晰。
  2. 请手动回滚事务
    声明事务的方法内,抛出异常后,请手动回滚事务。

更多场景

  1. 预防NPE空指针
  1. 如何在Lambda表达式中抛出异常?
  1. 合理使用Assert类,替代手动抛出异常。

结语

本文仅为分享个人日常学习笔记总结,也算是第一篇个人博客,边写边总结,难免错误与疏漏,如果你发现有错误和异议,麻烦第一时间指出。thanks!

参考博客与文档

阿里巴巴开发手册1.4版
IBM论坛:Java 异常处理的误区和经验总结
廖雪峰-java异常处理
Java 空指针异常的若干解决方案
技术总监手把手教我如何消除项目中丑陋的Try{}Catch{}