2017-07-21 146 views
1

我必須做一個函數調用。如果失敗,我再試2次。如果它在2次重試後仍然失敗,我會拋出異常。如何使用try catch重試機制爲for循環編寫更短,更高效的代碼?

下面是它的工作我當前的代碼:

for (int retry = 0; retry < 4; retry++) { 
     try { 
      callFunction(); 
      break; 
     } catch (Exception e) { 
      if (retry >= 0 && retry < 3) { 
       warn("callFunction failed. Retrying.." +(retry+1)); 
      } else { 
       warn("Retried maximum number of "+(retry+1)+" times. Failing the script"); 
       e.printStackTrace(); 
      } 
     } 
    } 

OUTPUT:

callFunction failed. Retrying..1 
callFunction failed. Retrying..2 
callFunction failed. Retrying..3 
Retried maximum number of 4 times. Failing the script 

我明白,這是不是即使它正在編寫的最有效方式。你能幫我重構一下這段代碼,以符合Java乾淨代碼的最佳實踐標準嗎?

+1

我投票結束這個問題作爲題外話,因爲它屬於[codereview.se]。 – shmosel

+1

另請閱讀[tag:coding-style]標籤的說明。 – shmosel

回答

4

什麼是沒有那麼大的位置:

  • 深嵌套
  • 冗餘retry >= 0條件
  • 反覆(retry + 1)
  • 重複使用的幻數的4

我想在這裏,while環路可能會更自然地流動, 並在最後檢查重試計數。

int maxRetries = 3; 
int retry = 0; 
Exception thrown = null; 

while (retry < maxRetries) { 
    try { 
    callFunction(); 
    break; 
    } catch (Exception e) { 
    thrown = e; 
    retry++; 
    warn("callFunction failed. Retrying.." + retry); 
    } 
} 

if (retry == maxRetries) { 
    warn("reached max"); 
    thrown.printStackTrace(); 
} 

其實,如果你把它變成一個函數就更好了。 將會有更少的變量:

void executeWithRetries(int maxRetries) { 
    Exception thrown = null; 

    for (int retry = 0; retry < maxRetries; retry++) { 
    try { 
     callFunction(); 
     return; 
    } catch (Exception e) { 
     thrown = e; 
     warn("callFunction failed. Retrying.." + retry); 
    } 
    } 

    warn("reached max"); 
    thrown.printStackTrace(); 
} 
+0

這有幫助。但是,當我嘗試在if(retry == maxRetries)塊中打印異常的堆棧跟蹤時,變量'e'超出了範圍。 '如果(重試== MAX_RETRY_COUNT){ \t \t警告( 「達到重試的最大次數失敗腳本。」); \t \t e.printStackTrace(); \t \t}' – InsecureNoob

+0

@InsecureNoob啊是的。你可以將它保存在一個變量中(更新我的答案)。 – janos

+0

這個工程!謝謝! – InsecureNoob

0

另一種方法是使用一個庫這樣的事情。使用Failsafe

RetryPolicy retryPolicy = new RetryPolicy().withMaxRetries(3); 
Failsafe.with(retryPolicy) 
    .onRetry((c, f, ctx) -> warn("callFunction failed. Retrying.." + ctx.getExecutions())) 
    .onFailure(e -> { 
    warn("Retried maximum number of times. Failing the script"); 
    e.printStackTrace(); 
    }); 
    .run(this::callFunction);