减少Java代码中的try-catch块以提高性能

时间:2014-05-19 12:24:20

标签: java exception-handling try-catch code-cleanup

我的任务是减少Java代码中的try-catch块以提高性能。但是每个try块都在检查一个完全不同的异常类型,以及自定义异常。如何减少try-catch块。

我的部分代码示例如下: -

        // Get a test engine and use that to initialize and save the test
        // taker
        TestEngine testEngine = null;
        try {
            testEngine = objFactory.getTestEngine(login.getTestengine());
        } catch (NoTestEngineException e) {
            // Add an error message, then throw the exception to struts to
            // handle
            request.setAttribute("errmsg", "Cannot create test engine: " + login.getTestengine());
            request.setAttribute("errcause", "exception.notestengine.cause");

            throw e;
        }

        //added for null check of variable testEngine
                if(testEngine==null)
                {
                    request.setAttribute("errmsg", "Could not obtain a testengine");
                }

        // Do we need to save the session id?
        String saveSessionId = objFactory.getConfigValue("testengine." + login.getTestengine() + ".recordjessionid", "false");
        String sessionId = null;
        if (saveSessionId.trim().equals("true")) {
            sessionId = request.getSession().getId();
        }



        Testtaker testTaker = null;
        try {
            testTaker = testEngine.buildTestTaker(login, null, sessionId, null, null);
        } catch (Exception e) {
            request.getSession().removeAttribute(ConstantLibrary.SESSION_LOGIN);

            CaslsUtils.outputLoggingData(log_, request);

            // Add an error message, then throw the exception to struts to
            // handle
            request.setAttribute("errmsg", "Cannot build a test taker.");
            request.setAttribute("errcause", "exception.testtakerbuildfailed.cause");

            //throw new NoTestTakerException("Failed to build testtaker.");
            throw e;
        }

5 个答案:

答案 0 :(得分:1)

如果在这种情况下每个块的异常类型不同,您可以将try块加到一个并使用单个try块添加多个catch块

try {
    TestEngine testEngine = objFactory.getTestEngine(login.getTestengine());

    //added for null check of variable testEngine
    if(testEngine==null) {
        request.setAttribute("errmsg", "Could not obtain a testengine");
    }

    // Do we need to save the session id?
    String saveSessionId = objFactory.getConfigValue("testengine." + login.getTestengine() + ".recordjessionid", "false");
    String sessionId = null;
    if (saveSessionId.trim().equals("true")) {
        sessionId = request.getSession().getId();
    }

    Testtaker testTaker = testEngine.buildTestTaker(login, null, sessionId, null, null);
} catch (NoTestEngineException e) {
    // Add an error message, then throw the exception to struts to
    // handle
    request.setAttribute("errmsg", "Cannot create test engine: " + login.getTestengine());
    request.setAttribute("errcause", "exception.notestengine.cause");

    throw e;
} catch (Exception e) {
    request.getSession().removeAttribute(ConstantLibrary.SESSION_LOGIN);

    CaslsUtils.outputLoggingData(log_, request);

    // Add an error message, then throw the exception to struts to
    // handle
    request.setAttribute("errmsg", "Cannot build a test taker.");
    request.setAttribute("errcause", "exception.testtakerbuildfailed.cause");

    //throw new NoTestTakerException("Failed to build testtaker.");
    throw e;
}

答案 1 :(得分:0)

您可以将两个try-catch块更改为一个:

TestEngine testEngine = null;
Testtaker testTaker = null;

try {
  testEngine = objFactory.getTestEngine(login.getTestengine()); 

  String saveSessionId = 
    objFactory.getConfigValue("testengine." + login.getTestengine() + ".recordjessionid", "false");

  String sessionId = saveSessionId.trim().equals("true") ? 
    request.getSession().getId() : null;

  testTaker = testEngine.buildTestTaker(login, null, sessionId, null, null);
}
catch (NoTestEngineException e) {
  // Add an error message, then throw the exception to struts to handle
  request.setAttribute("errmsg", "Cannot create test engine: " + login.getTestengine());
  request.setAttribute("errcause", "exception.notestengine.cause");

  throw e;
}
catch (Exception e) {
  request.getSession().removeAttribute(ConstantLibrary.SESSION_LOGIN);

  CaslsUtils.outputLoggingData(log_, request);

  // Add an error message, then throw the exception to struts to handle
  request.setAttribute("errmsg", "Cannot build a test taker.");
  request.setAttribute("errcause", "exception.testtakerbuildfailed.cause");

  throw e;
}

答案 2 :(得分:0)

我会像这样写

 public void someMethod(... args) throws Exception {
    // taker
    TestEngine testEngine = objFactory.getTestEngine(login.getTestengine());

    // Do we need to save the session id?
    String saveSessionId = objFactory.getConfigValue("testengine." + login.getTestengine() + ".recordjessionid", "false");
    String sessionId = null;
    if (saveSessionId.trim().equals("true")) {
        sessionId = request.getSession().getId();
    }

    Testtaker testTaker =  testEngine.buildTestTaker(login, null, sessionId, null, 
}

我会让调用者处理任何异常。

答案 3 :(得分:0)

与C ++不同,try-catch-finally块(异常)是Java的重要组成部分;它们应该被正确使用和使用。我也认为它们没有显着的性能影响;即使你没有抓住它们,它们也会被抛出(最终将被主线捕获)。但出于美学原因,您可以重新组织它们或使用单个方法作为整个方法,如:

method() {
 try {
 } catch (Ex1 e1) {
 } catch (Ex2 e2) {
 } finally {
 }
}

你也可以考虑处理它们,而不是再次抛出并处理调用堆栈中的每个方法(这可能有一点? - 性能影响..)..

答案 4 :(得分:0)

正如评论所指出的那样,try / catch块的数量不是问题 - 事实上你经常会遇到它们。

假设您已经分析了性能并且实际上这个方法给您带来了问题,您应该采取明显的步骤来避免抛出异常(并且因此将堆栈展开)。

例如,如果getTestEngine()调用后testEngine为空,则不会从方法返回,但是您将在testEngine.buildTestTaker()之后立即获得NPE,然后点击其中一个catch块。相反,如果testEngine为空,则应该从方法返回(使用适当的错误代码),避免堆栈展开惩罚。