【发布时间】:2013-11-14 22:25:48
【问题描述】:
我想了解try {} catch {} 块和堆栈跟踪的工作原理。
我正在阅读this great article about exception handling anti-patterns 并找到以下段落:
catch (NoSuchMethodException e) { throw new MyServiceException("Blah: " + e.getMessage()); }这会破坏原始异常的堆栈跟踪,并且总是错误的。
在那之后我意识到我并不真的知道try/catch 是如何工作的。我的理解如下。考虑这个例子:
void top() {
try {
f();
} catch (MyException ex) {
handleIt();
} finally {
cleanup();
}
}
void f() {
g();
}
void g() {
throw new MyException();
}
当我调用top()时,调用链top -> f -> g
在调用堆栈上留下两个stack frames(用于top 和f 函数)。当g 中引发异常时,
程序在执行堆栈中冒泡,直到找到处理异常的try/catch 块。同时它释放堆栈帧并将堆栈跟踪信息附加到一些可以传递给catch 的“魔术”对象,然后可以打印堆栈跟踪。
它如何知道被调用的函数被 try/catch 块“包围”了?此信息是否绑定到堆栈帧?比如,指向错误处理块的指针(一些开关选择匹配的catch 块),以及指向finally 块的指针?为什么e.getMessage() 在上面的示例中具有破坏性(参见 cmets)?
注意,我知道如何使用 try/catch 和异常,我想知道它在内部是如何工作的。
【问题讨论】:
-
嗯,你说得对,我没注意到
throw:) 但剩下的问题仍然有效
标签: java exception exception-handling stack