需要帮助了解内部尝试捕获和外部尝试捕获

时间:2015-08-04 03:35:33

标签: java

我已经找到了一些由另一位开发人员提交给我的代码。它有一个数据库调用,它有一个没有catch的内部try块,然后是一个带catch的外部try块。

我想要一些帮助,理解它的含义。因为内部try块没有捕获,这意味着数据库层中的任何异常都被忽略了吗?是否有外部try catch块只捕获getConnection和closeStatement的错误?

感谢您的帮助。

public int doKeywordSearch (
    String username,
    String sessionId,
    String[] keywords, 
    String status) throws RetekServiceException {

    int totalRecords = 0;
    Connection connection = null;
    CallableStatement callStmt = null;
    try {
        connection = DaoUtils.getDataSource().getConnection();      
        try {   
            callStmt = connection.prepareCall(DaoConstants.ITEM_SEARCH_KEYWORD_SQL);
            callStmt.setString(1, username);                                                    // p_vUsername
            callStmt.setString(2, sessionId);                                                   // p_vSid
            callStmt.setString(3, StringUtils.clean(keywords.length > 0 ? keywords[0] : null)); // p_vKeyword1 
            callStmt.setString(4, StringUtils.clean(keywords.length > 1 ? keywords[1] : null)); // p_vKeyword2
            callStmt.setString(5, StringUtils.clean(keywords.length > 2 ? keywords[2] : null)); // p_vKeyword3 
            callStmt.setString(6, StringUtils.clean(keywords.length > 3 ? keywords[3] : null)); // p_vKeyword4
            callStmt.setString(7, StringUtils.clean(keywords.length > 4 ? keywords[4] : null)); // p_vKeyword5
            callStmt.setString(8, status);                                                      // p_vStatus
            callStmt.registerOutParameter(9, OracleTypes.INTEGER);              
            callStmt.execute();
            totalRecords = callStmt.getInt(9);
            connection.commit();
        }
        finally {
            DaoUtils.closeStatement(callStmt);
        }
    }
    catch(SQLException e) {
        DaoUtils.doRollback(connection, e);
    }
    catch(NamingException e) {          
        throw new RetekServiceException("Could not do keyword search.", e);
    }
    finally {
        DaoUtils.closeConnection(connection);
    }                   
    return totalRecords;
}

4 个答案:

答案 0 :(得分:3)

try{} catch(){} finally {}不需要catchfinally,只需要其中一个。它是如何工作的,当一个catch块处理的异常被抛出try然后调用catch块时。否则,异常会像往常一样向上传播(确切地说它会被传播,我将在一分钟内解释)。无论是否发生异常,几乎都会调用 finally 块(请查看Java规范,以了解可能跳过finally块的极少数情况。)

如果在内部 try块中发生异常并且没有catch子句可以处理它,那么外部 {{1会尝试使用外部 try/catch的广告相应catch子句来处理它,否则如果外部<中不存在此类try/catch子句/ strong> catch然后异常将被传播(到调用此方法或一直到JVM的方法)。

实际上上面的例子没有多大意义,你可以将语句放在外部的finally块中......

正如其他人指出的那样,如果您使用的是java7和try/catch实施connection,您可以使用AutoCloseable,这将自动处理资源关闭,您将不会再次手动编写try-with-resources

答案 1 :(得分:2)

内部try / catch块的异常不会被忽略,它们被链抛到外部try / catch块(可能超出)。

如果try块中的任何语句失败,内部try / catch块的目的似乎是确保语句被关闭(在finally子句中)。

答案 2 :(得分:2)

内部示例是tryfinally块(注意缺少catch)。无论finally如何,都可以保证调用Exception块。但是,我会建议try-with-resources Statement

try (CallableStatement callStmt = connection.prepareCall(
        DaoConstants.ITEM_SEARCH_KEYWORD_SQL)) {
    // ...
}

这是保证callStmtclose(d)的另一种方法。

另见JLS-14.20.2. Execution of try-finally and try-catch-finally

答案 3 :(得分:1)

外部try-block仍将捕获内部try-block的异常。内部try-block用于确保调用DaoUtils.closeStatement(callStmt);