一些 Java 电子新闻简报订阅者表示他们对嵌套异常感到非常失望,说他们宁愿知道如何得到更少的信息,而不愿知道如何得到更多的信息。虽然丢弃可以用来调试的信息永远都不是一个好主意,但是少可以是多,而且 Java 1.4 提供了一个工具可以用于查明错误的起因。
这个工具是getStackTrace() 实用工具,它位于Throwable类中。getStackTrace() 返回Throwable对象被创建时所创建的StackTraceElement对象的一个数组。查询这些StackTraceElements可以准确地找出错误发生在什么地方。
对于调用getStackTrace() 时被调用的每个方法,返回的数组包含与它们相应的一个元素,另外返回的数组还包含一个元素来表明发出调用的代码。数组的第一个元素指出抛出最初异常的方法。要想获取你需要的信息,只要简单地调用适当的方法。
下面是说明getStackTrace() 用法的一个例子:
public class StackTraceTip {
public static void main(String args[])
{
StackTraceTip
s = new StackTraceTip();
try {
s.foo(Integer.parseInt(args[0]));
}
catch (Exception e) {
Throwable t = getRootCause(e);
//
print out root cause and handled exception for
//
comparison
System.out.println(e);
System.out.println(t);
StackTraceElement []trace = t.getStackTrace();
StackTraceElementste = trace[0];
System.err.println("error occurred in method: " +
ste.getMethodName());
System.err.println(" file:
" +
ste.getFileName());
System.err.println("
line number: " +
ste.getLineNumber());
}
}
public void foo(int y) {
if ( y > 1 ) {
throw
new IllegalArgumentException("invalid value:
" + y);
}
try {
bar(y);
}
catch (IllegalArgumentException
e) {
throw
new RuntimeException("bar threw error", e);
}
}
public void bar(int x) {
if ( x < 1 ) {
throw
new IllegalArgumentException("invalid value:
" + x);
}
}
public static ThrowablegetRootCause(Exception e) {
Throwable
root = e;
while (root.getCause()
!= null) {
root = root.getCause();
}
return root;
}
}
记住,堆栈跟踪所提供的信息量取决于代码如何编译——带调试信息或不带调试信息——以及代码正在运行在的虚拟机。所以,如果你使用这个方法获取信息,那么要准备好处理零长度的数组和没有文件名及行号的StackTraceElements。