我有这个代码 -
try {
doSomething();
} catch (Exception e) {
e.printStackTrace();
}
这将如何由编译器实际实现。生成的汇编代码中实际放置异常的检查在哪里?
更新
我知道上面的代码是如何翻译成字节码的。字节码仅将 try-catch 转换为相应的 try-handler block 。我感兴趣的是它将如何转换为程序集/和/或由 jvm 处理。
最佳答案
如果我没有正确理解你的问题,下面的代码
public class Example {
public static void main(String[] args) {
try {
otherMethod();
}
catch (Exception e) {}
try {
otherMethod();
someMethod();
}
catch (SQLException e) {}
catch (IOException e) {}
}
public static void someMethod() throws IOException {throw new IOException();}
public static void otherMethod() throws SQLException, IOException {}
}
产生以下(人类可读版本的摘录)字节码。
// main method
0: invokestatic #2 // Method otherMethod:()V
3: goto 7
6: astore_1
7: invokestatic #2 // Method otherMethod:()V
10: invokestatic #4 // Method someMethod:()V
13: goto 21
16: astore_1
17: goto 21
20: astore_1
21: return
Exception table:
from to target type
0 3 6 Class java/lang/Exception
7 13 16 Class java/sql/SQLException
7 13 20 Class java/io/IOException
您会注意到异常表
。此构造指示 VM,如果类型 type
的异常发生在从 from
到 to
的指令之间,则它必须 goto
指令(偏移量)目标
。它还指示它将 Exception
引用压入堆栈,以便可以复制其值并将其绑定(bind)到 catch
block 中的参数。
你还有这篇文章与上面的 throw
语句有关。
// someMethod method
0: new #6 // class java/io/IOException
3: dup
4: invokespecial #7 // Method java/io/IOException."<init>":()V
7: athrow
The instruction athrow
does the following
throws an error or exception (notice that the rest of the stack is cleared, leaving only a reference to the Throwable)
The objectref must be of type reference and must refer to an object that is an instance of class Throwable or of a subclass of Throwable. It is popped from the operand stack. The objectref is then thrown by searching the current method (§2.6) for the first exception handler that matches the class of objectref, as given by the algorithm in §2.10.
If an exception handler that matches objectref is found, it contains the location of the code intended to handle this exception. The pc register is reset to that location, the operand stack of the current frame is cleared, objectref is pushed back onto the operand stack, and execution continues.
If no matching exception handler is found in the current frame, that frame is popped. If the current frame represents an invocation of a synchronized method, the monitor entered or reentered on invocation of the method is exited as if by execution of a monitorexit instruction (§monitorexit). Finally, the frame of its invoker is reinstated, if such a frame exists, and the objectref is rethrown. If no such frame exists, the current thread exits.
因此堆栈帧不断弹出,直到找到一个可以处理抛出的异常为止。
How will this actually be implemented by the compiler. Where is the check for the exception actually put in the assembly code generated?
编译器生成上面的字节码。没有异常检查,只有字节码指令。 athrow
将指示 VM 执行我们称之为抛出异常的任务,这将导致弹出堆栈、在当前堆栈帧中搜索异常表等.
关于java - 如何在低(汇编)级别捕获和处理异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58936087/