5

Eclipse 4 给出了一个警告,指出stmt可能没有关闭并导致资源泄漏:

class Test {
    public void test() {
        PreparedStatement stmt = null;
        try {
            stmt = HibernateSession.instance().connection().prepareStatement("");
        } catch (final SQLException e) {
            e.printStackTrace();
        } finally {
            if (stmt != null)
                try {
                    stmt.close();
                } catch (final SQLException e) {
                    e.printStackTrace();
                }
        }
    }
}

什么情况下会出现这种情况?

4

4 回答 4

2

我想这里的结论是:这是一个 Eclipse 错误?

于 2013-02-27T03:21:59.093 回答
-1

stmt.close()如果在finally块中调用时抛出异常,则可能发生泄漏。

于 2013-02-27T01:24:46.530 回答
-1

问题是在您的finally块中可能会发生异常,这将阻止stmt关闭。

一种解决方法是您可以将finally块中的所有内容替换为:

JDBCUtilities.close(stmt);

参阅JDBCUtilities.close. _ 如您所见,使用此实用方法不会引发异常,因此您无需担心资源泄漏。另一个好处是实用程序方法也可以处理这种null情况,stmt因此我们不需要自己编写代码。

实际上,使用JDBCUtilities.

于 2013-02-27T01:55:45.530 回答
-2

您需要使用 Java 7 的 try 资源或 try-finally 块:

try(stmt = HibernateSession.instance().connection().prepareStatement("")) {


}

AutoCloseable将在继承自不保证关闭的类型上生成此警告。(或者可能Closeable,我忘记了)。

现在我明白了您的要求,只需编写不太复杂的代码即可。

Foo f = null; // don't do this, but it's what you're doing
f = new Foo();

是您正在做的事情,并且您发现了您实际上必须为这项无关工作支付罚款的几种情况之一。

此外,你try/finally应该是干净的。 .close()不能扔,为什么要抓?

try { // don't do this
    stmt.close();
}
catch(SQLException exc) {

}

应该生成一个 Eclipse 警告,告诉您您正在捕捉不会抛出的东西。这甚至可能是一个编译错误,不确定,但听起来你会受益于 Eclipse > Preferences > Compiler 并查看哪些警告是智能的。如果您不理解警告,请在 Google 上搜索,看看它是否对您有帮助,不要只是跳过它。(有点像你对这个做的)。

于 2013-02-27T01:23:01.947 回答