gpt4 book ai didi

java - JVM如何保证finally block 的执行?

转载 作者:IT老高 更新时间:2023-10-28 20:41:15 27 4
gpt4 key购买 nike

这个问题的目的是JVM如何能够保证finally block 的执行(前提是JVM没有崩溃并且线程没有中断或退出)。

在一个面试问题的提示下,我试图了解 JVM 如何确保即使在奇怪的情况下也能执行 finally block ......请考虑以下代码:

try{

int[] someArray = new int[10];
int invalid = someArray[10];
}
catch(IndexOutOfBoundsException e){

throw new RuntimeException("Other Exception");
}
finally{

//close open files or HTTP connections etc.
}


虽然这可能是一个奇怪的情况,但尽管 Other Exception 没有被明确处理,但是 finally block 仍然可以保证被执行。 JVM 是如何处理这种情况的?

我的想法:

根据我目前的理解和阅读,当遇到未处理的异常时,控制权会从当前线程转移(我认为是该线程的 ThreadGroup)。 ThreadGroup 中是否有一些规定可以检查需要执行的 finally block ?我唯一能想到的另一件事可能是 finally block 的地址存储在某个地方。然后 JVM 在检测到异常时执行 goto,并在 finally block 完成执行时返回异常。

谁能澄清这个过程实际上是如何发生的?

最佳答案

编译这个小程序(我意识到我应该使用你的例子,但没有区别)

public static void main(String[] args) {
try {
Float s = Float.parseFloat("0.0327f");
} finally {
System.out.println("hello");
}
}

我用过

>java -version 
java version "1.8.0-ea" // should be same for 7
Java(TM) SE Runtime Environment (build 1.8.0-ea-b118)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b60, mixed mode)

然后执行

javac -v -c <fully qualified class name>

获取字节码。你会看到类似

public static void main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=3, args_size=1
0: ldc #2 // String 0.0327f
2: invokestatic #3 // Method java/lang/Float.parseFloat:(Ljava/lang/String;)F
5: invokestatic #4 // Method java/lang/Float.valueOf:(F)Ljava/lang/Float;
8: astore_1
9: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
12: ldc #6 // String hello
14: invokevirtual #7 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
17: goto 31
20: astore_2
21: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
24: ldc #6 // String hello
26: invokevirtual #7 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
29: aload_2
30: athrow
31: return
Exception table:
from to target type
0 9 20 any
20 21 20 any
LineNumberTable:
line 10: 0
line 12: 9
line 13: 17
line 12: 20
line 14: 31
StackMapTable: number_of_entries = 2
frame_type = 84 /* same_locals_1_stack_item */
stack = [ class java/lang/Throwable ]
frame_type = 10 /* same */

您会注意到 finally 中的 代码出现两次,一次出现在 goto 之前一次之后。您还会注意到 Exception table它指定如果在某行发生异常时要转到哪个语句。

因此,如果语句 0-9 之间发生任何异常,请转到第 20 行并执行 finally 中的所有内容。 , 在 goto 之后.如果没有异常,执行finally然后执行goto跳过 finallygoto 之后.

在所有情况下,您都将执行 finally 中的代码。 block 。

Other Exception not being explicitly handled

使用 finally block ,Exception table将创建将处理 任何 类型的 Throwable 的条目.


Here's a listing of the bytecode instructions.

关于java - JVM如何保证finally block 的执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20963575/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com