簡體   English   中英

減少Java代碼中的try-catch塊以提高性能

[英]Reducing try-catch blocks in Java code to improve performance

我的任務是減少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;
        }

如果在這種情況下每個塊的異常類型都不同,則可以將try塊加入一個塊,然后將多個catch塊添加到一個try塊中

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;
}

您可以將兩個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;
}

我會這樣寫

 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, 
}

而且我會讓調用者處理任何異常。

與C ++不同,try-catch-finally塊(異常)是Java的基本組成部分。 它們應該被正確使用和使用。 我也不認為它們對性能有重大影響; 即使您沒有抓住它們,它們也將被拋出(最終將被主線程抓住)。 但是出於美學原因,您可以對其進行重新組織,或者將單個方法用於整個方法,如下所示:

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

您還可以考慮處理它們,而不是再次拋出該異常,並在調用堆棧中的每個方法中進行處理(這可能會對性能產生一點影響。)

正如評論所指出的那樣,try / catch塊的數目不是問題,這是事實,您是如此頻繁地擊中它們。

假設您已經分析了性能,而實際上正是這種方法給您帶來了問題,那么您應該采取顯而易見的步驟來避免引發異常(結果是堆棧被解開)。

例如,如果在調用getTestEngine()之后testEngine為null,則不會從該方法返回,但是您將在testEngine.buildTestTaker()之后立即獲得NPE,這將導致您的catch塊之一被擊中。 相反,如果testEngine為null,則應從方法中返回(帶有適當的錯誤代碼),以避免堆棧testEngine

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM