我昨天发现有趣的错误绊倒,并从固定它,但它仍然是今天早上困扰我,所以我想看看是否有人能在这个问题上提供一些线索。
有问题的代码:
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语句会抛出一个异常,表明getInt(INT)一直呼吁关闭的结果集。 我验证了事先准备好的声明中没有任何地方在代码中关闭,如果数据库被关闭,我会看到其他错误也是如此。 这使我相信,不知何故,偶尔,finally块被return语句之前执行。 我能想到的唯一的事情就是热点编译器并不总是得到这个权利。 我使用下面列出了Oracle JVM。
Java版本 “1.7.0_45”
的Java(TM)SE运行时环境(建立1.7.0_45-B18)
的Java的HotSpot(TM)64位服务器VM(建立24.45-B08,混合模式)
我觉得我应该提到,我已经看到了关于这个排序的其他问题的主机,但他们似乎都表明它是在石头上,在那里我似乎看到不同的东西设定。
的try-catch-最后,返回澄清
https://stackoverflow.com/questions/20164755/the-order-of-invoking-finally-block
最终是否总是在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
}
如果你有跟随一起的字节码指令 ,你会看到,在28
中, rs.getInt(1)
被调用,它的值存储在33
。 所述rs.close()
在调用35
。 所存储的值是在检索到40
,并在返回41
。
你所经历必须来自于你的代码中的一些其他问题。