我想了解try {} catch {}
块和堆栈跟踪是如何工作的。
我正在阅读这篇关于异常处理反模式的精彩文章,发现以下段落:
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
留下两个堆栈帧(用于top
和f
函数)。当在 中引发异常时g
,程序会在执行堆栈中冒泡,直到找到try/catch
处理异常的块。同时它释放堆栈帧并将堆栈跟踪信息附加到一些可以传递的“魔术”对象,catch
并且可以打印堆栈跟踪。
它如何知道被调用的函数被 try/catch 块“包围”了?此信息是否绑定到堆栈帧?比如,一个指向错误处理块的指针(一些开关选择一个匹配的catch
块),以及一个指向finally
块的指针?为什么e.getMessage()
在上面的例子中是破坏性的(见评论)?
注意,我知道如何使用 try/catch 和异常,我想知道它在.