这个问题的目的 是JVM如何保证finally块的执行 (前提是JVM不会崩溃并且线程不会中断或退出)。
在面试问题的提示下,我试图了解JVM如何确保即使在奇怪的情况下也可以执行finally块。请考虑以下代码:
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.
}
尽管这可能是一个奇怪的情况,但是即使未明确处理“ 其他异常”, 仍可以保证执行finally块。JVM如何处理这种情况?
据我到目前为止的了解和了解,当遇到未处理的异常时,控制权将从当前线程转移到(ThreadGroup
我认为是该线程)。可能有一些规定ThreadGroup
检查需要执行的finally块吗?我能想到的唯一的另一件事可能是finally块的地址存储在某个地方。然后,JVM在检测到异常时执行goto动作,并在finally块完成执行后返回该异常。
谁能澄清这个过程实际上是如何发生的?
编译这个小程序(我意识到我应该使用您的示例,但是没关系)
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
,如果在某行发生异常,则which指定要去的语句。
因此,如果在语句0-9之间发生任何异常,请转到第20行并在finally
之后执行内的所有内容goto
。如果没有异常,请执行finally
,然后goto
在finally
之后执行跳过goto
。
在所有情况下,您都将在finally
块内执行代码。
未明确处理其他异常
使用一个finally
块,Exception table
将创建一个条目,该条目将处理 任何 类型的Throwable
。
这是字节码指令的清单。
问题内容: 根据Java语言规范的第§14.20.2节 通过首先执行try块来执行带有finally块的try语句。然后有一个选择: 如果try块的执行正常完成,则执行finally块,然后可以选择: 如果finally块正常完成,则try语句正常完成。 如果finally块由于原因S突然完成,则try语句由于原因S突然完成 如果我正确地解释了它,那么在执行try块之后最终会被调用,但是所有这些如
问题内容: 考虑到此代码,我是否可以绝对确定该块始终执行,无论它是什么? 问题答案: 是的,将在执行或代码块后调用。 唯一不会被调用的时间是: 如果您调用 System.exit() 如果您调用 Runtime.getRuntime().halt(exitStatus) 如果JVM首先崩溃 如果JVM在try或catch块中达到了无限循环(或其他不间断,不终止的语句) 操作系统是否强行终止了JVM
问题内容: 考虑到此代码,我是否可以绝对确定该块始终执行,无论它是什么? 问题答案: 是的,将在执行或代码块后调用。 唯一不会被调用的时间是: 如果你调用 如果你调用 如果JVM首先崩溃 如果JVM在或catch块中达到了无限循环(或其他不间断,不终止的语句) 操作系统是否强行终止了JVM进程;例如,在UNIX上 如果主机系统死机;例如,电源故障,硬件错误,操作系统崩溃等 如果该块将由守护程序线程
本文向大家介绍java finally块执行时机全面分析,包括了java finally块执行时机全面分析的使用技巧和注意事项,需要的朋友参考一下 java里 finally 关键字通常与try catch块一起使用。用来在方法结束前或发生异常时做一些资源释放的操作。最近也看到网上有一些讨论try catch finally关键词执行的顺序的文章,并给出了finally块是在方法最后执行的。 这些
问题内容: 在Java 块中,无论try / catch中发生了什么,通常都认为其中的代码可以“保证”运行。但是,我知道至少有两种情况 不会 执行: 如果被调用;要么, 如果异常一直抛出到JVM,并且发生默认行为(即退出) 是否有其他程序行为会阻止块中的代码执行?代码将在什么特定条件下执行或不执行? 编辑: 正如NullUserException所指出,第二种情况实际上是不正确的。我以为是因为标准
本文向大家介绍try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?相关面试题,主要包含被问及try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?时的应答技巧和注意事项,需要的朋友参考一下 finally 一定会执行,即使是 catch 中 return 了,catch 中的 return