Java语言在设计之初就提供了相对完善的异常处理机制,本文 主要对比的讲述 Exception 和 Error,以及实践中的选择
Exception 和 Error 都是继承 Throwable 类,在Java中只有 Throwable 类型的实例才能被抛出 (throw) 或者捕获 (catch),它是异常处理机制的基本组成类型
Exception 和 Error 体现了 Java 平台设计者对不同异常情况的分类,Exception 是程序正常运行中,可以预料的意外情况,可能并且应该被捕获并进行相应的处理
Error 是指在正常情况下,不大可能出现的情况,绝大部分的 Error 都会导致程序处于非正常,不可恢复状态,是不需要捕获的,常见的如 OutOfMemoryError
Exception 又分为可检查 (checked)异常 和不可检查 (unchecked)异常,可检查异常在源代码里必须显示进行捕获处理,这是编译期检查的一部分
不检查异常就时所谓的运行时异常,类似 NullPoniterExcption 之类,通常是编码可以避免的错误,具体根据需求判断是否需要捕获,并不会再编译期强制要求
直观的体现出更多的信息,而不是简单的 Exception 之类,恰恰会隐藏我们的目的,另外,我们也需要保证程序不会捕获我们不希望的异常,比如,你可能更希望 RuntimeException 被扩散出来,而不是被捕获
try{ // 业务代码 Thread.sleep(1000L); }catch(Exception e){ e.printStackTrace(); }这里,应该捕获Thread.sleep() 抛出的InterruptException 异常
对可恢复的情况使用检查异常, 对编程错误使用运行时异常对于未受检的异常:运行时异常 和 Error,它们都是不需要也是不应该被捕获的异常,如果程序抛出未受检的异常或者错误,往往都是属于不可恢复的情形,继续执行下去也是有害无益的
如果期望调用者能够设当恢复,对于这种情况就应该使用受检异常
不要忽略异常这是异常处理中特别需要注意的事情,忽略异常,往往是假设这段代码可能不会发生,或者感觉忽略也无所谓,如果我们不把异常抛出来,或者没有输出到日志之类,程序可能在后续代码中以不可控制方式结束,造成后期很难定位错误
不要使用 printStackTrace()方式记录异常标准出错会直接输出到控制台上,而且产生大量字符串,不是一个合适的输出选项,在一些复杂的分布式系统中,如果异常,很难追踪到堆栈轨迹