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

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

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

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

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

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


当前回答

其余解决方案的问题是,对应的函数在没有时间间隔的情况下连续尝试,从而溢出堆栈。

为什么不一刻不停地尝试呢?

这里有一个使用setTimeout和递归函数的解决方案:

(function(){ try{ Run(); //tries for the 1st time, but Run() as function is not yet defined } catch(e){ (function retry(){ setTimeout(function(){ try{ console.log("trying..."); Run(); console.log("success!"); } catch(e){ retry(); //calls recursively } }, 1000); //tries every second }()); } })(); //after 5 seconds, defines Run as a global function var Run; setTimeout(function(){ Run = function(){}; }, 5000);

将函数Run()替换为希望每秒重试的函数或代码。

其他回答

你需要像这样在while循环中封装try-catch: -

int count = 0;
int maxTries = 3;
while(true) {
    try {
        // Some Code
        // break out of loop, or return, on success
    } catch (SomeException e) {
        // handle exception
        if (++count == maxTries) throw e;
    }
}

我已经采取了count和maxTries,以避免运行到一个无限循环,以防异常继续发生在你的try块。

解决这个问题的一个简单方法是在while循环中包装try/catch并维护一个计数。通过这种方式,您可以根据其他变量检查计数,同时维护故障日志,从而防止出现无限循环。这不是最精致的解决方案,但它是可行的。

https://onlinegdb.com/a-7RsL1Gh

    public void doSomething() throws Exception{
      final int MAX_TRIES = 10;
      int count = 0;
      
      while(count++ < MAX_TRIES){
         try{ 
            System.out.println("trying");
            causeIssue(count); // throws error/exception till count 2
            System.out.println("trying successful");
            break; // break on success
         } catch (Exception e){
           System.out.println("caught, logging Exception:" + count);
         } catch (Error e){
           System.out.println("caught, logging Error:" + count);
         }
      }
    }

输出:

trying
caught, logging Error:1
trying
caught, logging Error:2
trying
trying successful

我知道这里已经有很多类似的答案,我的答案也没有太大不同,但我还是会把它贴出来,因为它涉及一个具体的案例/问题。

当你在PHP中处理facebook Graph API时,你有时会得到一个错误,但立即重新尝试同样的事情会得到一个积极的结果(由于各种神奇的互联网原因,超出了这个问题的范围)。在这种情况下,不需要修复任何错误,而是简单地再试一次,因为有某种“facebook错误”。

这段代码在创建facebook会话后立即使用:

//try more than once because sometimes "facebook error"
$attempt = 3;
while($attempt-- > 0)
{
    // To validate the session:
    try 
    {
        $facebook_session->validate();
        $attempt = 0;
    } 
    catch (Facebook\FacebookRequestException $ex)
    {
        // Session not valid, Graph API returned an exception with the reason.
        if($attempt <= 0){ echo $ex->getMessage(); }
    } 
    catch (\Exception $ex) 
    {
        // Graph API returned info, but it may mismatch the current app or have expired.
        if($attempt <= 0){ echo $ex->getMessage(); }
    }
}

此外,通过让for循环计数为零($attempt——),可以很容易地改变将来的尝试次数。

使用带有本地状态标志的while循环。初始化标志为false,并在操作成功时将其设置为true,如下所示:

  boolean success  = false;
  while(!success){
     try{ 
         some_instruction(); 
         success = true;
     } catch (NearlyUnexpectedException e){
       fix_the_problem();
     }
  }

这将不断重试,直到成功。

如果你只想重试一定次数,那么也可以使用计数器:

  boolean success  = false;
  int count = 0, MAX_TRIES = 10;
  while(!success && count++ < MAX_TRIES){
     try{ 
         some_instruction(); 
         success = true;
     } catch (NearlyUnexpectedException e){
       fix_the_problem();
     }
  }
  if(!success){
    //It wasn't successful after 10 retries
  }

这将尝试最多10次,如果不成功,直到那时将退出,如果它成功之前。