exception传播指导(Java)

在Java中有exception传播的指导吗?

何时向方法签名添加exception? 例如:如果只有一个基本程序资源丢失时才会抛出exception,并且只能在顶层处理exception,那么是否通过使用此exception的所有方法通过使用erring方法的所有方法来传播它?

有什么好的做法吗? 任何不好的做法?

我很抱歉,如果我是模糊的,但我只是寻找一些关于例外编程风格(一般)的build议。

过去帮助我的准则包括:

  • 当方法不能处理exception时抛出exception ,更重要的是由调用者处理。 一个很好的例子发生在Servlet API中 – doGet()和doPost()在请求无法被正确读取的某些情况下抛出ServletException或IOException。 这两种方法都不能处理exception,但容器是(在大多数情况下会导致50x错误页面)。
  • 如果方法无法处理,则冒泡 。 这是上述推论,但适用于必须捕捉exception的方法。 如果捕获的exception不能通过该方法正确处理,则最好将其冒泡。
  • 立即抛出exception 。 这可能听起来含糊不清,但是如果遇到exception情况,那么抛出一个指示原始失败点的exception是一个好习惯,而不是试图通过错误代码来处理失败,直到一个被认为适合抛出exception的点。 换句话说,试图最小化混合exception处理与error handling。
  • loggingexception或冒泡,但不要同时执行这两个操作 。 loggingexception通常表明exception堆栈已经完全展开,表明exception没有发生进一步冒泡。 因此,不build议同时执行这两个操作,因为这往往会导致debugging过程中令人沮丧的体验。
  • 除了调用者处理exception时,使用java.lang.Exception (checked exceptions)的子类 。 如果调用方不处理exception,则会导致编译器引发错误消息。 但是要小心,这通常会导致开发人员“吞食”代码中的exception。
  • 使用java.lang.RuntimeException的子类(未经检查的exception)来表示编程错误 。 这里推荐的exception类包括IllegalStateException , IllegalArgumentException , UnsupportedOperationException等等。再次,必须注意使用exception类,如NullPointerException(几乎总是一个不好的做法抛出一个)。
  • 使用exception类层次结构来传递跨各层的exception信息 。 通过实现层次结构,您可以在调用方中概括exception处理行为。 例如,您可以使用像DomainException这样的根exception,其中有几个子类,如InvalidCustomerException,InvalidProductException等等。这里需要注意的是,如果您将每个单独的exception情况表示为单独的exception,则exception层次结构可能会非常迅速地爆炸。
  • 避免捕捉你无法处理的exception 。 很明显,但很多开发人员试图捕获java.lang.Exception或java.lang.Throwable。 由于所有的子类exception都可以被捕获,所以当“全局”exception类被捕获时,应用程序的运行时行为常常是模糊的。 毕竟,人们不想捕捉到OutOfMemoryError – 应该如何处理这种exception呢?
  • 小心包装exception 。 重试exception会重置exception堆栈。 除非原来的原因被提供给新的exception对象,否则它将永远丢失。 为了保留exception堆栈,必须提供原始的exception对象给新exception的构造函数。
  • 只有在需要时才将检查的exception转换为未经检查的exception 。 当包装一个exception时,可能会包装一个检查的exception并抛出一个未选中的exception。 这在某些情况下很有用,特别是当意图中止当前正在执行的线程时。 但是,在其他情况下,这可能会导致一些痛苦,因为编译器检查不会执行。 因此,将检查过的exception作为一个未经检查的exception调整并不意味着盲目地完成。

你应该尽快处理这个方法,但它必须是有道理的。 如果exception没有意义的被你的方法抛出,但你不能处理它,把它包装到另一个exception,并抛出这个新的exception。

关于exception的一个不好的做法是把它们都抓住(它不是口袋妖怪,它是java!),所以避免catch(Exception e)或者catch(Throwable t)