应用中经常出现处理一个异常时抛出另一个异常。实际上,第一个异常引发了第二个异常。知道什么时候一个异常引发另一个是非常有帮助的。链式异常帮助程序员获取这个信息。

Throwable的这些方法或构造器支持链式异常。

Throwable getCause()
Throwable initCause(Throwable)
Throwable(String, Throwable)
Throwable(Throwable)

initCause和构造器中的Throwable参数是引发当前异常的异常。getCause返回引发当前异常的异常,而initCause设置引发当前异常的异常。

下面的例子展示了怎么使用链式异常。

try {

} catch (IOException e) {
    throw new SampleException("Other IOException", e);
}

在一个例子中,捕获了一个IOException,基于原始的原因创建了一个新的SampleException异常,并把异常链抛给更高级别的异常处理器。

访问堆栈跟踪(stack trace)信息

现在假设更高级别的异常处理器想要用自己的格式处理堆栈跟踪信息.

定义:堆栈跟踪提供当前线程的执行历史信息,并且列出在异常发生的那个时间点所有被调用过的类名称和方法名称。堆栈跟踪是一个非常有用的调试工具,当一个异常抛出的时候你很应该充分利用这一点。

下面的代码展示了如何调用异常对象的getStackTrace方法:

catch (Exception cause) {
    StackTraceElement elements[] = cause.getStackTrace();
    for (int i = 0, n = elements.length; i < n; i++) {     
        System.err.println(elements[i].getFileName()
            + ":" + elements[i].getLineNumber()
            + ">> "
            + elements[i].getMethodName() + "()");
    }
}

Logging API

下面的代码在catch代码块加入了一小段日志。然而,它不是手工解析堆栈跟踪信息,并把它发送到System.err()。而是使用 java.util.logging 包中的日志功能把它输出到一个文件中。

try {
    Handler handler = new FileHandler("OutFile.log");
    Logger.getLogger("").addHandler(handler);
   
} catch (IOException e) {
    Logger logger = Logger.getLogger("package.name");
    StackTraceElement elements[] = e.getStackTrace();
    for (int i = 0, n = elements.length; i < n; i++) {
        logger.log(Level.WARNING, elements[i].getMethodName());
    }
}





原文地址