`
night_lone
  • 浏览: 63332 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Best Practices for Exception Handling(异常处理最佳实践)

    博客分类:
  • J2SE
阅读更多

在JE中一为仁兄的博客中看到一篇关于异常的好文章。

原文地址:http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html

所以也想来温习哈异常知识。

优秀的程序员都想写出质量高的代码,就必须控制好异常的用法,异常用的好,可以优化代码,否则,就会产生副作用,因为如果没有把异常用好的话,异常反而会导致你的程序变慢,因为需要去花费内存和CPU资源去创建异常,抛出异常,捕获异常。还有,如果过多的使用异常,会导致程序很难看,头疼。

 

所以用好异常很重要。要不偏不倚,要小心的运用。

 

会抛出异常的三种情况:

  1.Exceptions due to programming errors。

  2.Exceptions due to client code errors

  3.Exceptions due to resource failures

 

在JAVA中,主要有两大种类型的异常:

  1.Checked exceptions:客户端代码必须处理API抛出的这类异常,该类异常继承于Exception。

  2.Unchecked exceptions所有继承于 RuntimeException的异常都特殊对待,客户端代码不需要处理API抛出的这类异常。

 

关于异常这个话题,在JAVA社区和C++社区一直辩论不休。辩论的主题起源于:JAVA好像是第一个主流的带有checked Exception的面向对象的语言。C++和C#中没有checked Exception,他们中的所有异常都是unchecked Exception。

 

到底什么是Checked Exception?

     它就是一种在低层方法中抛出,在高层调用方法中强制处理。

    如果客户端代码(client code)不能高效的处理异常,Checked Exception这种强制执行,就会加重API和client code之间的负担。

 

有的程序员会采取这样的捷径:制止异常在一个空的catch块中,或者仅仅在方法中抛出异常,其实这就是把负担转移给客户端的调用者。

 

废话说了那么多,现在来看看主题,怎么样去设计一个合适的抛出异常的API?

 1.当选择异常类型checked 或Unchecked时候,就问自己:当异常发生时,客户端代码能做什么?

      如果客户端代码能够恢复异常,就选择checked异常;如果客户端不能做什么,就选择Unchecked Exception.

输出一点错误日志,对恢复并没有作用。

 

异常类型选择标准
异常发生时客户端的反映  异常类型
客户端代码不能做任何事  unchecked  Exception
 客户端代码根据异常信息会采取有用的恢复的action  checked  Exception

 

 

 

 

 

 

 

一般对于程序性错误,更喜欢选择unchecked Exception.因为它不会强迫客户端API去明显的处理它们。一般我们更倾向地使用标准的API,不会去设计自己的Exception.

 

2.保护封装性

永远不让有特殊实现的checked Exception扩大到更高的层。比如:不要让来自数据访问层的SQLException传播到业务逻辑对象层。业务逻辑层根本不需要知道 SQLException。有两种方法可以来优化:

    一,Convert SQLException into another checked exception, if the client code is expected to recuperate from the exception.

    二,Convert SQLException into an unchecked exception, if the client code cannot do anything about it.

 

一般情况下,客户端代码不会做任何事情,所以不要迟疑去把它转换成unchecked Exception。

看看下面的代码段:

public void dataAccessCode(){
    try{
        ..some code that throws SQLException
    }catch(SQLException ex){
        ex.printStacktrace();
    }
}

 上面的catch块,仅仅禁止了代码的执行,并没有做任何事情。既然我们的客户端代码不能对异常做任何事情,为何不将上面的代码写成如下这样:

public void dataAccessCode(){
    try{
        ..some code that throws SQLException
    }catch(SQLException ex){
        throw new RuntimeException(ex);//关键,抛出unchecked Exception
    }
}

 上面的代码已经将SQLException转换成了RuntimeException,如果 SQLException发生,就将抛出一个新的 RuntimeException.这时程序的执行就会被搁置,异常被报告。这样做的好处是,不会让不必要异常处理破坏业务逻辑层的数据。

 如果你有信心在业务逻辑层能够恢复SQLException 异常,也可以将SQLException转换成一个更有意义的checked exception.但是我发现在大多数情况下, RuntimeException足以应付了。

 

3.不要创建不能给客户端代码提供任何信息的异常。

看看下面的代码有什么错误?

public class DuplicateUsernameException
    extends Exception {}

 因为它没有给客户端代码提供任何有用的信息,只是显示出是一个异常。Exception类也象其他普通的类一样,也可以在类中提供方法,给客户端代码调用而取得一些信息。

我们可以给 DuplicateUsernameException添加一些有用的方法。

public class DuplicateUsernameException
    extends Exception {
    public DuplicateUsernameException 
        (String username){....}
    public String requestedUsername(){...}
    public String[] availableNames(){...}
}

 这样客户端代码就可以调用requestedUsername()方法获取请求的用户名信息,如果不想添加额外的信息,也就可以抛出一个标准的异常,如:

throw new Exception("Username already taken");

 更好的,你如果认为客户端代码不会做任何事,只是输出一个日志信息,就可以这样做:抛出一个unchecked Exception

throw new RuntimeException("Username already taken");

 

下面是使用异常应该注意的技巧:

1. Always clean up after yourself

    如果你正在使用数据库连接或网络连接这样的资源,你必须确定清理掉它们。如果你调用的API也仅仅是调用的unchecked exception的话,使用完资源后,也要注意用try--finally blocks来清理。

比如:

public void dataAccessCode(){
    Connection conn = null;
    try{
        conn = getConnection();
        ..some code that throws SQLException
    }catch(SQLException ex){
        ex.printStacktrace();
    } finally{
        DBUtil.closeConnection(conn);//关闭连接,清理资源
    }
}

class DBUtil{
    public static void closeConnection
        (Connection conn){
        try{
            conn.close();
        } catch(SQLException ex){
            logger.error("Cannot close connection");
            throw new RuntimeException(ex);//抛出unchecked exception
        }
    }
}

 DBUtil就是一个用来关闭连接的工具类。关键点就是finally 块的使用,无论异常是否被捕获,它都会执行。

 

 

2. Never use exceptions for flow control

 

3. Do not suppress or ignore exceptions

 

4. Do not catch top-level exceptions

 

5. Log exceptions just once

 

 

 

分享到:
评论

相关推荐

    Microsoft WinCE6.0 Exam Preparation Kit for the Microsoft Certified Technology Specialist (MCTS)

    - Best practices for optimizing the run-time image for different hardware configurations. **6. Developing Multi-threaded System Applications** - Principles of multi-threading and its importance in ...

    UIPATH_RAP_Developer_Advanced(online quiz).docx

    在自动化项目中,遵循最佳实践是非常重要的。开发者需要遵循一些基本原则,例如删除无用的变量、删除禁用代码等,以提高项目的可读性和可维护性。 UiPath Robotic Enterprise Framework UiPath Robotic Enterprise...

    oracle-pl-sql-programming-5th-edition

    Like its predecessors, this fifth edition of Oracle PL/SQL Programming covers language fundamentals, advanced coding techniques, and best practices for using Oracle’s powerful procedural language....

    log4j-tutorial.zip_How To Change It

    This tutorial explains how to set up log4j with email, files and stdout. It compares XML to properties configuration files, ...Furthermore, we explain best practices on logging and exception handling.

    common-sense-c-advice-and-warnings-for-c-and-c-programmers.9781882419005.32087

    The chapter covers best practices for defining and using macros, including the importance of understanding macro expansion. Other topics include avoiding common pitfalls related to preprocessor ...

    vc编程系列之Addison Wesley - Exceptional C++

    1. 异常处理(Exception Handling):C++中的异常处理机制是其强大特性之一,用于在程序中优雅地处理错误。书中详细介绍了何时、如何以及为何要使用try、catch和throw语句,以及如何设计和使用异常安全的代码。 2. ...

    Core Java Volume I Fundamentals, 11th Edition

    Master foundational techniques, idioms, and best practices for writing superior Java code Leverage the power of interfaces, lambda expressions, and inner classes Harden programs through effective ...

    Struts2 权威指南 配套源码 第16章

    6. **异常处理(Exception Handling)**:Struts2提供了一套优雅的异常处理机制,包括全局异常映射和动作级别的异常处理。这部分可能详细阐述如何配置和实现自定义的异常处理器。 7. **国际化...

    Essential Windows Communication Foundation For .NET Framework 3.5

    The authors approach each subject with practical advice and present best practices, tips, and tricks for solving problems. Throughout, you’ll find detailed explanations, solutions for the “pain ...

    PHP Objects, Patterns, and Practice, 4th Edition

    This edition introduces new object relevant features such as traits, reflection extension additions, callable type hinting, improvements to exception handling, and many smaller language enhancements....

    WCF.Multi-Layer.Services.Development.with.Entity.Framework.4th.Edition

    Apply best practices to your WCF services and utilize Entity Framework to access underlying data storage A step-by-step, practical guide with nifty screenshots to create six WCF and Entity Framework ...

    C#文件加密实例源码.rar

    8. **Best Practices(最佳实践)**:源码可能还展示了如何安全地存储和传递密钥,以及如何利用加密服务提供者(CSP,Cryptographic Service Provider)等安全组件。 通过分析这个实例源码,你可以了解到如何在C#中...

    Essential C# 5.0-Englis

    This edition also includes C# Coding Guidelines that call attention to today's best practices for writing C# code. Separate indexes of C# versions 3.0, 4.0, and 5.0 make it easy to find answers ...

    c#图书管理系统源代码.pdf

    9. **最佳实践(Best Practices)**: 虽然这个登录示例简化了实际应用中的许多细节,但在真实的系统中,通常会使用更安全的方法来处理用户认证,例如哈希和盐值对密码进行加密,以及使用参数化查询或存储过程来...

    SCJP6 Sun Certificated Programmer for Java 6 Study Guide (Exam 310-065) 英文原版

    - **Best Practices**: Following guidelines for maintainable and efficient code. ### Conclusion The SCJP6 Sun Certified Programmer for Java 6 Study Guide (Exam 310-065) is a comprehensive resource ...

    Mule in Action, 2nd Edition

    Exception handling and transaction management with Mule Chapter 10. Securing Mule Chapter 11. Tuning Mule Part 3: Traveling further with Mule Chapter 12. Developing with Mule Chapter 13. Writing ...

    asp用户注册

    7. **安全实践(Security Best Practices)**:为了确保用户数据的安全,开发者需要遵循一些最佳实践,如使用HTTPS协议传输敏感数据、避免SQL注入、限制密码尝试次数等。 8. **角色管理(Role Management)**:在...

Global site tag (gtag.js) - Google Analytics