gpt4 book ai didi

java - Final block 何时相对于 Return 运行

转载 作者:太空宇宙 更新时间:2023-11-04 07:12:56 25 4
gpt4 key购买 nike

我昨天偶然发现了一个有趣的错误,并已修复它,但今天早上它仍然困扰着我,所以我想看看是否有人可以阐明这个问题。

有问题的代码:

final ResultSet rs = prepStatement.executeQuery();
try
{
if (!rs.next())
{
throw new IllegalStateException("Expected non-empty result");
}
return rs.getInt(0 + 1);
}
finally
{
rs.close();
}

现在来说说从那以后就没有制作的部分。每隔一段时间,return 语句就会抛出一个异常,表明已在关闭的 ResultSet 上调用了 getInt(int)。我验证了准备好的语句没有在代码中的任何地方关闭,如果数据库正在关闭,我也会看到其他错误。这让我相信,有时,finally block 会在 return 语句之前执行。我唯一能想到的是热点编译器并不总是能做到这一点。我正在使用下面列出的 Oracle JVM。

java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)

我觉得我应该提到,我已经看到了有关此顺序的许多其他问题,但它们似乎都表明它是一成不变的,而我似乎正在见证一些不同的东西。

Try-catch-finally-return clarification
https://stackoverflow.com/questions/20164755/the-order-of-invoking-finally-block
Does finally always execute in Java?

最佳答案

我编写并编译了以下类

public class Examples {
public int answer(PreparedStatement prepStatement) throws SQLException {
final ResultSet rs = prepStatement.executeQuery();
try {
if (!rs.next()) {
throw new IllegalStateException("Expected non-empty result");
}
return rs.getInt(1);
} finally {
rs.close();
}
}
}

使用以下命令

[s_delima@ml-l-sotiriosd Downloads]$ java -version
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
[s_delima@ml-l-sotiriosd Downloads]$ javac Examples.java
[s_delima@ml-l-sotiriosd Downloads]$ /usr/java/latest/bin/javap -c Examples
Compiled from "Examples.java"
public class Examples {
public Examples();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return

public int answer(java.sql.PreparedStatement) throws java.sql.SQLException;
Code:
0: aload_1
1: invokeinterface #2, 1 // InterfaceMethod java/sql/PreparedStatement.executeQuery:()Ljava/sql/ResultSet;
6: astore_2
7: aload_2
8: invokeinterface #3, 1 // InterfaceMethod java/sql/ResultSet.next:()Z
13: ifne 26
16: new #4 // class java/lang/IllegalStateException
19: dup
20: ldc #5 // String Expected non-empty result
22: invokespecial #6 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
25: athrow
26: aload_2
27: iconst_1
28: invokeinterface #7, 2 // InterfaceMethod java/sql/ResultSet.getInt:(I)I
33: istore_3
34: aload_2
35: invokeinterface #8, 1 // InterfaceMethod java/sql/ResultSet.close:()V
40: iload_3
41: ireturn
42: astore 4
44: aload_2
45: invokeinterface #8, 1 // InterfaceMethod java/sql/ResultSet.close:()V
50: aload 4
52: athrow
Exception table:
from to target type
7 34 42 any
42 44 42 any
}

如果您跟随byte code instructions ,您将看到在 28 处,调用了 rs.getInt(1) 并将其值存储在 33 处。 rs.close()35 处调用。存储的值在 40 处检索并在 41 处返回。

您所遇到的情况必须来自代码中的其他点。

关于java - Final block 何时相对于 Return 运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20380869/

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