异常处理的基本原则

来源:互联网 发布:宠物翻译器软件下载 编辑:程序博客网 时间:2024/06/06 01:48

总原则:”Throw early catch late" principle

This is probably the most famous principle about Exception handling. It basically says that you should throw an exception as soon as you can, and catch it late as much as possible. You should wait until you have all the information to handle it properly.

This principle implicitly says that you will be more likely to throw it in the low-level methods, where you will be checking if single values are null or not appropriate. And you will be making the exception climb the stack trace for quite several levels until you reach a sufficient level of abstraction to be able to handle the problem.

 

1、什么时候抛异常

      “If your method encounters an abnormal condition that it can't handle, it should throw an exception.”

   

     判断准则:

     “Avoid using exceptions to indicate conditions that can reasonably be expected as part of the typical functioning of the method.

     (1)当方法返回值无法表达当前程序遇到的状况的时候,抛出异常(比如DataInputStream的readInt方法,返回-1,无法判断说是文件到了尽头,因为-1可能是数据的一部分)

 

2、入参校验——关于preconditions

Always validate user input in very early stage, even before it reached to actual controller. It will help you to minimize the exception handling code in your core application logic. It also helps you in making application consistent if there is some error in user input.

One design approach often discussed in the context of object-oriented programming is the Design by Contract approach. This approach to software design says that a method represents a contract between the client (the caller of the method) and the class that declares the method. The contract includes preconditions that the client must fulfill and postconditions that the method itself must fulfill.

    因而衍生出一个原则:

   “if an event represents an "abnormal condition" or a "broken contract," the thing to do in Java programs is to throw an exception.”

    对于入参的校验,采用  Bouncer Pattern 的模式进行实现(即:CheckAtTheGate模式,Security Door Pattern,google guava的preconditions就是采用此模式进行方法入参校验的)


  也可以不采用抛异常的方式,而是采用流程控制的方式,但对方法的返回值有特殊的要求(要求返回值既能承载方法本身要返回的类型,比如list,也需要能承载错误消息),对于mvc的controller返回的model and view,就是这样的数据结构,因而可以直接采用流程控制方式进行入参处理;但是servcie层则不一样,如果过度要求返回类型可以承载错误消息的话,则在设计或实现上会表现出很强的侵入性。

 

 

3、检查与非检查异常的使用原则

     “If you are throwing an exception for an abnormal condition that you feel client programmers should consciously decide how to handle, throw a checked exception.”

       “That is the trick, then, of deciding between a checked and an unchecked exception. If the abnormal condition is a failure of the method to fulfill its contract, and you feel it is common or important enough that client programmers should be forced to deal with the possibility of the exception, throw a checked exception. Otherwise, throw an unchecked exception.


   (1)checked exception  “If you throw a checked exception (and don't catch it), you will need to declare the exception in your method's throws clause. Client programmers who wish to call your method will then need to either catch and handle the exception within the body of their methods, or declare the exception in the throws clause of their methods. Making an exception checked forces client programmers to deal with the possibility that the exception will be thrown.

   (2)unchecked exception  “With an unchecked exception, however, the compiler doesn't force client programmers either to catch the exception or declare it in a throws clause. In fact, client programmers may not even know that the exception could be thrown. 

 

4、异常定义的原则 : Dont Throw Generic Exceptions

      比如在抛接口调用失败的异常的时候,先细分到每个外部系统,再细分某个具体的接口。

      “One theory is that you should throw the most specific exception that still makes sense to the caller. If you need to declare a new subclass to describe the problem, so be it. It may worth creating a whole new domain-specific hierarchy of exceptions, rooted in Exception, to provide information at the appropriate level of abstraction.

      

5、异常捕获原则:

    “Let exceptions propagate higher up the call chain, rather than handling them right away.

    “Handling Exceptions As Early As Possible“  (尽早转换为自定义异常,特别是一些checked异常)

    ”Catch What You Can Handle” (根据需要,转换为自定义异常,然后在最顶层捕获处理)

 

 

6、过度使用异常——使用异常控制流程(没有必要,而且违反了PrincipleOfLeastAstonishment原则)

     Dont Use Exceptions For Flow Control

 

 

7、一些使用原则的总结

Here is a collection of the exception guidelines put forth by this article:

  • If your method encounters an abnormal condition that it can't handle, it should throw an exception.

  • Avoid using exceptions to indicate conditions that can reasonably be expected as part of the normal functioning of the method.

  • If your method discovers that the client has breached its contractual obligations (for example, by passing in bad input data), throw an unchecked exception.

  • If your method is unable to fulfill its contract, throw either a checked or unchecked exception.

  • If you are throwing an exception for an abnormal condition that you feel client programmers should consciously decide how to handle, throw a checked exception.

  • Define or choose an already existing exception class for each kind of abnormal condition that may cause your method to throw an exception.

 

 

8、best practice

(1)Never swallow the exception in catch block

(2)Declare the specific checked exceptions that your method can throw

(3)Do not catch the Exception class rather catch specific sub classes

(4)Never catch Throwable class

(5)Always correctly wrap the exceptions in custom exceptions so that stack trace is not lost

(6)Either log the exception or throw it but never do the both

(7)Never throw any exception from finally block

(8)Always catch only those exceptions that you can actually handle

(9)Don't use printStackTrace() statement or similar methods

(10)Use finally blocks instead of catch blocks if you are not going to handle exception

(11)Remember "Throw early catch late" principle

(12)Always clean up after handling the exception

(13)Throw only relevant exception from a method

(14)Never use exceptions for flow control in your program

(15)Validate user input to catch adverse conditions very early in request processing

(16)Always include all information about an exception in single log message

(17)Pass all relevant information to exceptions to make them informative as much as possible

(18)Always terminate the thread which it is interrupted

(19)Use template methods for repeated try-catch

(20)Document all exceptions in your application in javadoc

 

 

 

 

参考文献:

1、Designing with exceptions :Guidelines and tips on when and how to use exceptions




http://m.oschina.net/blog/201687

0 0