首页 > 解决方案 > 即使我们已经处理了语句,SonarLint 仍然显示阻止程序错误,连接在 finally 块中关闭

问题描述

SonarLint 显示以下错误:

  1. '使用 try-with-resources 或在“finally”子句中关闭此“语句”。'
  2. '使用 try-with-resources 或在“finally”子句中关闭此“连接”。'
    即使我们在 finally 块中关闭了 Statement stmt、Connection con,也会出现阻塞错误。

请找到示例代码。

public String getProductNumber() throws BusinessDelegateException {

        String productNo = null;
        Connection con = null;
        Statement stmt = null;
        ResultSet   rs  = null;
        String query  = //some query
        try {
            DataSource ds = getDataSource();
            con = ds.getConnection();
            stmt = con.createStatement();
            rs   = stmt.executeQuery(query);
            productNo =.......
            ....................
        }catch (Exception e) {
            String errorMsg = "Error occured in getProductNumber()";
            throw new BusinessDelegateException(errorMsg, e);
        }finally{
            try {
                if(rs != null)
                    rs.close();
                if (stmt != null)
                    stmt.close();
                if (con != null)
                    con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        return productNo;
    }

我们能够通过以下方式修改 finally 块来解决问题。但它似乎仍然是 catch 块的重复。我们还有其他方法可以解决这个问题吗?

finally{
        try {
            if(rs != null)
                rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (stmt != null)
                stmt.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (con != null)
                con.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

标签: javasonarlint

解决方案


如果没有 try-with-resources,您只能通过使用可重用方法来改进代码,调用 main 方法:

closeResources(rs, stmt, con);

这将为每个资源调用不同的方法,例如语句:

 public void closeResource(Statement stmt) {
    if (stmt != null) {
        stmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    }

顺便说一句,你最好使用 logger 而不是e.printStackTrace()

对于完整的解决方案,您可以查看在数组中添加资源并在循环中关闭它们的广泛示例:

for (Closeable resource : resources) {
   try {
     resource.close();

推荐阅读