5.4 异常链
应用程序通常会通过抛出另一个异常来响应异常。实际上,第一个异常引起第二个异常,以此类推,这就是“异常链(Chained Exceptions)”。异常链有助于用户知道什么时候一个异常会导致另一个异常。以下是Throwable中支持异常链的方法和构造函数:
· Throwable getCause()
· Throwable initCause(Throwable)
· Throwable(String, Throwable)
· Throwable(Throwable)
initCause和Throwable构造函数的Throwable参数是导致当前异常的异常。getCause返回导致当前异常的异常,initCause设置当前异常的原因。
以下示例显示如何使用异常链:
在此示例中,当捕获到IOException时将创建一个新的SampleException异常,附加原始的异常原因,并将异常链抛出到下一个更高级别的异常处理程序。
5.4.1 访问堆栈跟踪信息
现在让我们假设更高级别的异常处理程序想要以自己的格式转储堆栈跟踪。
注意
堆栈跟踪(stack trace)提供有关当前线程的执行历史信息,并列出在异常发生时调用的类和方法的名称。堆栈跟踪是一个有用的调试工具,通常在抛出异常时会使用。
在异常对象上调用getStackTrace方法可获取堆栈跟踪信息,代码如下:
5.4.2 记录异常日志
如果要记录catch块中所发生的异常,最好不要手动解析堆栈跟踪并将输出发送到System.err(),而是使用Java日志框架(比如java.util.logging)将日志的内容输出发送到文件。
以下是使用日志框架的示例:
java.util.logging是Java自身提供的日志框架。除此之外,业界还提供了诸如Log4j、Logback和SLF4J等第三方开源的日志框架。这些框架往往拥有比较好的性能。
· Log4j是Apache旗下的Java日志记录工具,它是由Ceki Gülcü首创的。
· Log4j 2是Log4j的升级产品。
· Commons Logging是Apache基金会所属的项目,是一套Java日志接口,之前叫Jakarta Commons Logging,后更名为Commons Logging。
· SLF4J(Simple Logging Facade for Java)类似于Commons Logging,是一套简易Java日志门面,本身并无日志的实现。同样也是Ceki Gülcü首创的。
· Logback是SLF4J的实现,与SLF4J是同一个作者。
这些框架都能很好地支持UDP以及TCP协议。应用程序将日志条目发送到控制台或文件系统。通常使用文件回收技术来避免日志填满所有磁盘空间。
日志处理的最佳实践之一是关闭生产中的大部分日志条目,因为磁盘I/O的成本很高。磁盘I/O不但会减慢应用程序的运行速度,还会严重影响可伸缩性。将日志写入磁盘也需要较高的磁盘容量,当磁盘用完之后,就有可能会降低应用程序的性能。日志框架提供了在运行时控制日志记录的选项,以限制必须打印的内容以及不打印的内容。这些框架中的大部分都对日志记录控件提供了细粒度的控制,还提供了在运行时更改这些配置的选项。
另外,日志可能包含重要的信息,如果分析得当,那么可能具有很高的价值。因此,限制日志条目本质上限制了我们理解应用程序行为的能力。所以,日志是一把双刃剑。