Java 异常总结

Java 程序设计语言提供了三种可抛出结构(throwable):

  • 受检异常(checked exception)
  • 运行时异常(run-time exception)
  • 错误(error)

受检异常

在决定使用受检的异常或者是未受检的异常时,主要的原则是:如果期望调用者能够适当的恢复,对于这种情况就要使用受检异常。通过抛出受检异常,强迫调用者在一个 catch 子句中处理该异常,或者将它传播出去。

未受检异常

有两种未受检的可抛出结构:运行时异常(run-time exception) 和错误。

在行为上两者是等同的:它们都是不需要也不应该被捕获的可抛出结构,这种异常往往属于不可恢复的情形,继续执行下去有害无益。如果程序没有捕捉到这样的可抛出结构,将会导致当前线程停止(halt),并出现适当的错误信息。

用运行时异常来表明编程错误。

大多数的运行时异常表示前提违例(precondition violation)。所谓前提违例是指 API 的客户没有遵守 API 规范建立的约定。你实现的所有未受检的抛出结构应该是 RuntimeException 的子类。

对于可以恢复的情况,使用受检的异常;对于程序错误,则使用运行时异常。

异常也是一个完全意义上的对象,可以在它上面定义任意的方法。该方法的主要用途是为捕获异常的代码而提供额外的信息,特别是关于引发这个异常条件的信息。

优先使用标准的异常

专家级程序员和缺乏经验的程序员的一个最主要的区别就是,专家追求并且通常页呢能够实现高度的代码重用。

代码重用是值得提倡的,这是一条通用的规则,异常也不例外。

Java 平台类库提供了一组基本的未受检的异常,他们满足了绝大多数 API 的异常抛出需要。

重用现有的异常有多方面的好处

  • 它使你的 API 更加易于学习和使用,因为它与程序员熟知的习惯用法是一致的
  • 对于用到的这些 API 程序而言, 可读性更好,因为不会出现很多程序员不熟悉的异常。

IllegalArgumentException 是最经常被重用的。因为接收对象的状态而使调用非法,通常就会抛出这个异常。可以这么说,所有错误的方法调用都可以被归结为非法参数或者非法状态

IllegalStateException 是因为接收对象的状态而使调用非法,通常就会抛出这个异常。

但是,其他还有一些标准异常也被用于某些特定情况下的非法参数和非法状态。

如,NullPointerException 针对传入参数为 null 的情况。IndexedOutOfBoundsException 针对

此外,还有一些异常,如 ConcurrentModificationException。如果一个对象被设计为专用于单线程或者与外部同步机制配合使用,一旦发现它正在(或者已经)被并发的修改,就应该抛出这个异常。

另外一个UnsupportedOperationException 。如果对象不支持所请求的操作,就会抛出这个异常。如果某个异常能够满足你的需要,就不要犹豫,使用就是,不过,一定要确保抛出异常的条件与该异常的文档中描述的条件一致。

抛出与抽象对应的异常

如果方法抛出的异常与它所执行的任务没有明显的联系,这种情形将会使人不知所措。

为避免此类问题,更高层的实现应该捕获低层次的异常,同时抛出可以按照高层抽象进行解释的异常。这种做法称为异常转译(exception translation)。

不要忽略异常

不管异常代表了可预见的异常条件,还是编程错误,用空的 catch 块忽略它,将会导致程序在遇到错误的情况下悄然的执行下去。然后,有可能在未来的某个点上,当程序不能容忍与错误源明显相关的问题时,它就会失败。

正确的处理异常功能能够彻底挽回失败。只要将异常传播给外界,至少会导致程序迅速的失败,从而保留了有助于调试该失败条件的信息。

不建议使用 printStackTrace()

就是printStackTrace()打印出的堆栈日志跟正常输出或者业务代码执行日志是交错混合在一起的,在并发日志输出多的情况下,查看异常日志就变更的非常困难,因为一块日志都不在一起了。

printStackTrace()默认使用了System.err输出流进行输出,与System.out是两个不同的输出流,那么在打印时自然就形成了交叉。再就是输出流是有缓冲区的,所以对于什么时候具体输出也形成了随机。

看到这里就明白了,如果想简单的让输出顺序话,给printStackTrace()指定一个输出流就可以了,例如printStackTrace(System.out)

在项目中一般都是使用logback、log4j这类框架统一打印日志,好处多多。

posted @ 2019-06-02 17:54  ReyCG  阅读(397)  评论(0编辑  收藏  举报