How does `try / catch` work in details(`try/catch` 是如何工作的)
问题描述
我想了解 try {} catch {}
块和堆栈跟踪的工作原理.
我正在阅读 这篇关于异常处理的好文章模式 并找到以下段落:<块引用>
catch (NoSuchMethodException e) {throw new MyServiceException("废话:" +e.getMessage());}
这会破坏原始异常的堆栈跟踪,并且总是错误的.
在那之后我意识到我并不真的知道 try/catch
是如何工作的.我的理解如下.考虑这个例子:
void top() {尝试 {F();} 捕捉(MyException ex){处理它();} 最后 {清理();}}无效 f() {G();}无效 g() {抛出新的 MyException();}
当我调用 top()
时,调用链 top ->f ->g
在调用堆栈上留下两个 堆栈帧(对于 top
和 f
函数).当 g
中引发异常时,程序在执行堆栈中冒泡,直到找到处理异常的 try/catch
块.同时它释放堆栈帧并将堆栈跟踪信息附加到一些可以传递给 catch
的魔术"对象,并且可以打印堆栈跟踪.
它如何知道被调用的函数被 try/catch 块包围"了?此信息是否绑定到堆栈帧?比如,指向错误处理块的指针(一些开关选择匹配的 catch
块),以及指向 finally
块的指针?为什么 e.getMessage()
在上面的例子中是破坏性的(见评论)?
注意,我知道如何使用 try/catch 和异常,我想知道它在内部是如何工作的.
怎么知道被调用的函数被try/catch块包围"了?"
每个方法的代码包含异常表,它描述了该方法的所有 try-catch 块.
当一个过程(函数、方法)被调用时,当前堆栈帧会附加调用指令的地址,以便在正确的指令处(调用指令的下一个)恢复该帧的执行.
执行 throw 语句时,JVM 检查每个堆栈帧 以确定该帧是否可以处理异常.如果它的方法包含一个包含调用指令的try-catch块,并且块的异常类型是抛出异常的超类型(或相同),则可以.如果找到这样的帧,则该帧将从 try-catch 块指向的指令恢复其执行.
I would like to the innards of how does try {} catch {}
block and stack traces work.
I was reading this great article about exception handling anti-patterns and found the following paragraph:
catch (NoSuchMethodException e) { throw new MyServiceException("Blah: " + e.getMessage()); }
This destroys the stack trace of the original exception, and is always wrong.
After that I realized that I don't really know how try/catch
works. My understanding is the following. Consider the example:
void top() {
try {
f();
} catch (MyException ex) {
handleIt();
} finally {
cleanup();
}
}
void f() {
g();
}
void g() {
throw new MyException();
}
When I call top()
, the call chain top -> f -> g
leaves two stack frames on the call stack (for top
and f
functions). When the exception is raised in g
,
the program bubbles up the execution stack until it finds try/catch
block that handles the exception. Meanwhile it frees the stack frames and attach stack trace information to some "magic" object that can be passed to catch
and the stack trace can be printed.
How does it know that the called function is "surrounded" with the try/catch block? Is this information bound to the stack frame? Like, a pointer to error handling block (some switch selecting a matching catch
block), and a pointer to finally
block? Why e.getMessage()
is destructive in the example above (see the comments)?
Note, I know how to use try/catch and exceptions, I want to know how does it work inside.
"How does it know that the called function is "surrounded" with the try/catch block?"
The code of each method contains Exception Table which describes all try-catch blocks of that method.
When a procedure (function, method) is called, the current stack frame is appended with the address of the calling instruction, so as to restore execution of that frame at the correct instruction (next after calling instruction).
When a throw statement is executed, the JVM examines each stack frame to find out if that frame can handle the exception. It can if its method contains a try-catch block which contains the calling instruction, and the type of block's exception is a supertype (or the same as) of the thrown exception. If such a frame is found, the frame restores its execution from the instruction pointed to from the try-catch block.
这篇关于`try/catch` 是如何工作的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:`try/catch` 是如何工作的
基础教程推荐
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01