【问题标题】:Re-do an object with iterative for loop用迭代 for 循环重新做一个对象
【发布时间】:2013-07-16 15:56:26
【问题描述】:

我有一个这样的 for 循环:

for (Environment environment : environmentList) {
//do stuff
}

我在循环中捕获异常,但想用接收异常的对象重试执行代码。显然,我可以通过使用计数器和列表索引的 for 循环来做到这一点,但我很好奇是否有任何方法可以做到这一点。

细化,

for (Environment environment : environmentList) {
try{
//do stuff
}catch(exception)
{} //retry code using current environment
}

【问题讨论】:

    标签: java loops for-loop error-handling iteration


    【解决方案1】:

    您可以在 for 循环中使用另一个循环:

    for (Environment environment : environmentList) {
        while (true) {
            try{
    
            }catch(exception) {
               continue;  // Exception: continue while
            }
            break;  // No exception: break while.
        }
    }
    

    但实际行为将取决于您在 try 块中所做的事情。例如,如果您更改 environment 变量,那么您可能无法再次获得原始的 environment。在这种情况下,一个选项是在 while 循环中使用 environment 的块范围副本。

    【讨论】:

      【解决方案2】:

      当您捕获异常时,为什么不将当前(失败的)环境添加到列表中,如果您有很多失败,该列表会逐渐增加。然后您可以再次尝试所有失败的条目吗?

      如果你进行递归调用,你必须小心,因为这可能会永远持续下去。然后,您可以对该方法施加一些限制...

      也许是这样的......

      yourMethod(Enviroment[] enviromentList, int attempt)
      {
              switch(attempt)
              {
      
              case FIRST_ATTEMPT:
                   for(Enviroment enviroment : enviromentList)
                   {
                       try{
                            //YOUR CODE
                            }catch (Exception e){
                            failedList.add(enviroment);
                           }
                    }
                    yourMethod(failedList, SECOND_ATTEMPT);///RECURSIVE CALL BUT PASS IN CONSTRAINT
      
              case SECOND_ATTEMPT:
                  //YOUR STUFF AGAIN
              }
      }
      

      【讨论】:

      • 是的,但是我可以按照@RohitJain 的建议使用嵌套的 while 循环来实现这样的约束。不过,很好的答案,我会考虑将失败添加到黑盒测试列表中。谢谢。
      【解决方案3】:

      不是本地的。您必须自己编写代码。

      请记住,这充满了困难。如果您的可重试块总是失败会发生什么?你想反复循环吗?如果它完成了之前完成的一半,会发生什么?你想让它重做一遍吗?这种重试机制执行起来相对容易,但要考虑的后果也很多。

      一些可重试组件的伪代码。您可以将其抽象为(例如)RetryingExecutor 并提供Callable/Runnable 以实际执行您的代码。

      while (count < max) {
         try {
           return execution();
         }
         catch (Exception e) {
            count++;
         }
      
      }
      throw new Exception("Failed after " + count + " attempts");
      

      【讨论】:

      • 感谢您编辑您的帖子以包含这些问题,考虑这些问题非常重要。但是,我知道该块不会总是失败。我正在使用一项服务进行查询并且非常努力地打击它,这些例外是偶尔的结果。我也没有时间限制,无论考虑多么重要。好帖子,谢谢。
      【解决方案4】:

      如果您希望自动处理重试,可以使用Sarge 之类的库。

      Plan plan = Plans.retryOn(TimeoutException.class, 5, Duration.mins(1)).make();
      
      Sarge sarge = new Sarge();
      MailService service = sarge.supervise(MailService.class, plan);
      
      service.doSomething(); // Method is retried if TimeoutException is thrown
      

      【讨论】:

        猜你喜欢
        • 2016-08-03
        • 2020-11-17
        • 2013-10-15
        • 1970-01-01
        • 1970-01-01
        • 2017-02-08
        • 2014-11-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多