异常处理的 15 个处理原则

红薯 发布于 2012/02/01 09:40
阅读 6K+
收藏 39

见过很多人在进行异常处理的时候,直接一个 e.printStackTrace() 就完成了,这是一种非常粗陋的做法,首先会导致应用日志的大量错误信息,而很多时候你都不知道这些错误信息因何发生;再者,反应到用户端将直接导致用户无法获取操作的结果以及失败的原因。

以下 15 条异常处理的原则来自国外的博客

  1. 不用使用异常来管理业务逻辑,应该使用条件语句。如果一个控制逻辑可通过 if-else 语句来简单完成的,那就不用使用异常,因为异常会降低代码的可读性和性能,例如一些 null 的判断逻辑、除0的控制等等;

  2. 异常的名字必须清晰而且有具体的意思,表示异常发生的问题,例如 FileNotFoundException 就很清晰直观

  3. 当方法判断出错该返回时应该抛出异常,而不是返回一些错误值,因为错误值难以理解而且不够直观,例如抛出 FileNotFoundException 异常,而不是返回 -1 或者 -2 之类的错误值。

  4. 应该捕获指定的异常,而不是 catch(Exception e) 了事,这对性能、代码的可读性以及诸多方面都有好处

  5. Null 的判断逻辑并不是一成不变的,当方法允许返回 null 的时候使用 if-else 控制逻辑,否则就抛出 NullPointerException

  6. 尽量不要二次抛出异常,如果非得这么做的话,抛出同一个异常示例,而不是重新构建一个异常对象,这对性能是有帮助的,而且外层调用者可获取真实的异常信息

  7. 定义你自己的异常类层次,例如 UserException 和 SystemException 分别代表用户级别的异常信息和系统级别的异常信息,而其他的异常在这两个基类上进行扩展

  8. 明确的使用不同的异常类型:
    Fatal: System crash states.
    Error: Lack of requirement.
    Warn: Not an error but error probability.
    Info: Info for user.
    Debug: Info for developer.

  9. 不要仅仅捕获异常而不做任何处理,不便于将来维护

  10. 不要多次重复记录同一个异常,这可以让我们清晰的了解异常发生的位置

  11. 请使用 finally 来释放一些打开的资源,例如打开的文件、数据库连接等等

  12. 大部分情况下不建议在循环中进行异常处理,应该在循环外对异常进行捕获处理

  13. 异常的粒度很重要,应该为一个基本操作定义一个 try-catch 块,不要为了简便,将几百行代码放到一个 try-catch 块中

  14. 为你的异常生成足够的文档说明,至少是 JavaDoc

  15. 为每个异常消息定义一个数值,这对好的文档来说是非常重要的。

你有其他的补充吗?请不吝赐教。

加载中
0
0
六只
六只
异常处理确实水很深。
voov
voov
+10086
0
盐巴2012
盐巴2012
第15条非常有用,应该放上面
0
盐巴2012
盐巴2012
定义一个通用的bean作为返回值,把返回值以及异常、状态标记等都放在这个bean里面返回出去
0
准码农
准码农
很有用,学习一下。。。。
0
coda
coda
1. 只针对异常情况才使用异常。如下例,使用异常是很不妥当的:
 
    /**
    * 判断用户输入的是否是整数格式的字符串
    */
    private boolean isIntegerString(String str) {
      try {
          Integer.parseInt(str);
      } catch (NumberFormatException e) {
          return false;
      }
      return true;
    }
2.  不仅异常,一般的变量命名也尽量要有意义,不能过于宽泛。变量可见范围越大,就越要注意命名。
      当然,异常命名清晰,针对性强时,更有利于我们排查解决问题,更进一步,一般异常类都有 public Exception(String message) 这样的构造函数,以便于我们传递异常的一些关键信息,我们可以在个信息时放入便于我们调试,修复问题的一些关键的参数和其它利于我们定位错误的信息。
 
3.  如果不想返回一些难懂的错误状态代码,又不想扔出异常,强迫客户端去通过捕捉异常来控制程序流程,可以提供一些便利的状态检测方法。如List的 boolean isEmpty()方法,我们在list.get(0)之前可以先调用此方法而不是一堆的catch(IndexOutOfBoundsException):
    /**
    * 用<code>,</code> 连接字符数组
    */
    private String join(List<String> strList) {
        if(null == strList || strList.isEmpty()) {
            return "";
        }
        
        StringBuilder sb = new StringBuilder();
        for (String s : strList) {
            sb.append(s).append(',');
        }
        sb.setLength(sb.length() -1);
        return sb.toString();
    }
 
4.  该捕获指定的异常,并且应该处理异常,我们都知道一般不应该默默地吃掉异常,但还是经常看到这样的代码:
    try {
        // ...
    } catch (Exception e) { }
 
6.  jdk1.4 新增 Exception(Throwable cause),Exception(String message, Throwable cause)两个构造方便大家对底层异常类进行包装抽象。
7.  对应到java世界来,一个是免检异常RuntimeException,一般用于表示系统级或框架级别异常、编程错误等;一个是受检Exception, 一般用于表示程序异常,此类异常一般希望客户端程序员进行恢复。
8.  请问这条是针对日志记录吗?
9.  同第4条。如果你要跳槽了,这么做吧!然后恶狠狠地对接手的程序员兄弟说:哥们,你死定了!
0
整理秀逗的脑袋
整理秀逗的脑袋
不错啊,有章可循的。
0
0
foucsj
foucsj

1. http://www.cnblogs.com/focusj/archive/2011/12/26/2301524.html这是我总结而异常的基础知识。

2. 异常对性能是有一定的影响的。

3. 对于第六条中:外层调用者可获取真实的异常信息,这个用异常链就可以将异常信息保存。java的分层架构,BUSINESS层的异常体系就可以准确的抛出DAO层的异常。

返回顶部
顶部