哪些JVM指令不能抛出?

时间:2014-10-02 11:44:47

标签: jvm try-catch bytecode

是否有任何JVM指令保证不会抛出?

如果我理解正确,spec或多或少表示可能随时抛出VirtualMachineError。 因此,这两种方法在所有情况下可能不一定表现相同:

int foo() {
  try { return 1; }
  catch (Throwable t) { return 2; }
}

int bar() { return 1; }

是否有任何情况(除非try块为空),在删除try-catch后保证行为保持不变?

2 个答案:

答案 0 :(得分:1)

你问的是错误的问题。如果您希望抛出VirtualMachineError,则无论是否存在try … catch,您都无法保证行为保持不变。

坚持你的榜样:

try { return 1; }
catch (Throwable t) { return 2; }

对于此代码,将有两个字节代码指令iload_1ireturn的异常处理程序。这意味着如果在VirtualMachineError指令之前或在JVM遇到iload_1指令之后立即引发ireturn,则不会捕获错误。当删除异常处理程序并在这些指令之间引发错误时,没有人可以区分这种情况。

The Java® Virtual Machine Specification, Java SE 8 Edition §2.10. Exceptions比较:

  

Java虚拟机可能允许在抛出异步异常之前执行少量但有限的执行。允许此延迟允许优化代码在遵循Java编程语言的语义的同时检测并抛出这些异常,以便处理它们。

因此对于VirtualMachineError的情况,缺少异常处理程序没有任何区别,没有人会注意到它,JVM可能会推迟错误,具体取决于代码优化的内部状态。另一种情况是ireturn抛出IllegalMonitorStateException的可能性。

毕竟,问题是你要优化什么。异常处理程序通常没有性能影响,因为只要没有异常处理,JVM就不会触及它们。

答案 1 :(得分:0)

理论上,一切都可以抛出异常。但无论如何,这种例外情况都是不可治愈的,你也可以让异常停止你的申请。