Try-catch是用来帮助异常处理的。这意味着它将在某种程度上帮助我们的系统变得更加健壮:尝试从意外事件中恢复。

我们怀疑在执行和指令(发送消息)时可能会发生一些事情,因此它被包含在try中。如果发生了几乎意想不到的事情,我们可以做些什么:我们编写捕获。我不认为我们调用只是为了记录异常。我认为catch块是为了给我们从错误中恢复的机会。

现在,假设我们从错误中恢复,因为我们可以修复错误。如果能再试一次,那就太好了:

try{ some_instruction(); }
catch (NearlyUnexpectedException e){
   fix_the_problem();
   retry;
}

这将很快陷入永恒循环,但让我们假设fix_the_problem返回true,然后重试。假设在Java中没有这样的东西,你将如何解决这个问题?你认为解决这个问题的最佳设计代码是什么?

这就像一个哲学问题,因为我已经知道Java不直接支持我所要求的内容。


当前回答

你可以使用https://github.com/bnsd55/RetryCatch

例子:

RetryCatch retryCatchSyncRunnable = new RetryCatch();
        retryCatchSyncRunnable
                // For infinite retry times, just remove this row
                .retryCount(3)
                // For retrying on all exceptions, just remove this row
                .retryOn(ArithmeticException.class, IndexOutOfBoundsException.class)
                .onSuccess(() -> System.out.println("Success, There is no result because this is a runnable."))
                .onRetry((retryCount, e) -> System.out.println("Retry count: " + retryCount + ", Exception message: " + e.getMessage()))
                .onFailure(e -> System.out.println("Failure: Exception message: " + e.getMessage()))
                .run(new ExampleRunnable());

你可以传递自己的匿名函数,而不是新的ExampleRunnable()。

其他回答

https://github.com/tusharmndr/retry-function-wrapper/tree/master/src/main/java/io

int MAX_RETRY = 3; 
RetryUtil.<Boolean>retry(MAX_RETRY,() -> {
    //Function to retry
    return true;
});

如果不是所有异常都需要重试,那么只有一些例外。如果至少要尝试一次,这里有一个替代的实用方法:

void runWithRetry(Runnable runnable, Class<Exception> exClass, int maxRetries) {
        Exception err = null;
        do {
            maxRetries--;
            try {
                runnable.run();
                err = null;
            } catch (Exception e) {
                if(exClass.isAssignableFrom(e.getClass())){
                    err = e;
                }else {
                    throw e;
                }
            }
        } while (err != null && maxRetries > 0);

        if (err != null) {
            throw err;
        }
    }

用法:

    runWithRetry(() -> {
       // do something
    }, TimeoutException.class, 5)

简单的

int MAX = 3;

int count = 0;
while (true) {
    try {
        ...

        break;
    } catch (Exception e) {
        if (count++ < MAX) {
            continue;
        }

        ...
        
        break;
    }
}

我不确定这是否是“专业”的方式来做这件事,我不完全确定它是否适用于所有事情。

boolean gotError = false;

do {
    try {
        // Code You're Trying
    } catch ( FileNotFoundException ex ) {
        // Exception
        gotError = true;
    }
} while ( gotError = true );

如果它是有用的,可以考虑更多的选项,所有放在一起(停止文件而不是重试,睡眠,继续更大的循环)都可能有帮助。

 bigLoop:
 while(!stopFileExists()) {
    try {
      // do work
      break;
    }
    catch (ExpectedExceptionType e) {

       // could sleep in here, too.

       // another option would be to "restart" some bigger loop, like
       continue bigLoop;
    }
    // ... more work
}