导语
经常在项目中碰到各式各样的异常处理方式,各有风格但又较为混乱,对我一个新手程序员照成了很多使用上的困惑和疑虑。
本篇文章基于项目中异常使用和处理进行学习和总结,希望对各位小伙伴有所帮助!
异常的选择
- 自定义业务异常包含原始异常(或堆栈信息),方便调用方快速定位问题。
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);
}
}
- 合理的异常分层
- DAO层:SQL异常,数据库连接池异常,MYBATIS异常等;
- Service层:封装DAO层异常,并加入业务异常;
- Web 层:对业务异常进行捕获并处理。
- 避免直接使用RuntimeException
使用有业务含义的自定义异常。推荐业界已定义 过的自定义异常,如:DAOException / ServiceException等。
异常处理
捕获异常的处理应当遵循以下原则:
- 切勿把异常捕获当作流程控制
同阿里巴巴开发手册所述:异常设计的初衷是解决程序运行中的各种意外情况,且异常的处理效率比条件判断方式 要低很多! - 要么处理要么抛出
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
}
- 通知调用方更多的异常相关信息
尽可能详细通知调用方,在什么情况下会抛出哪种异常(包含返回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);
- 最终调用方必须处理和打印异常
可利用框架aop->SpringMVC统一异常处理,将异常的处理织入到框架的最外层进行处理,这样的好处不言而喻,你不需要到处try...catch,更加的简洁清晰。 - 请手动回滚事务
声明事务的方法内,抛出异常后,请手动回滚事务。
更多场景
- 预防NPE空指针
- 养成严谨的思维习惯,拆装箱,取值,使用对象/集合前,都预先进行判空。
- 利用JSR 303 - Bean Validation对入参进行判断。
- 利用java8-Optional对象防止空指针。
- 抽离方法或转函数式接口方式@FunctionalInterface。
- 使用包装器处理抛出的异常。(个人推荐:throwing-function)
- 合理使用Assert类,替代手动抛出异常。
结语
本文仅为分享个人日常学习笔记总结,也算是第一篇个人博客,边写边总结,难免错误与疏漏,如果你发现有错误和异议,麻烦第一时间指出。thanks!
参考博客与文档
阿里巴巴开发手册1.4版
IBM论坛:Java 异常处理的误区和经验总结
廖雪峰-java异常处理
Java 空指针异常的若干解决方案
技术总监手把手教我如何消除项目中丑陋的Try{}Catch{}