如何创建一个try-catch块继续调用对象上的方法,直到没有更多的异常要捕获

问题描述 投票:1回答:4

基本上遍历列表, - 在第一个对象上调用方法 - 赶上第一个例外(如果有的话);如果没有更多的例外可以捕获,请正常返回。否则,继续调用方法,直到捕获到所有异常。 - 转到下一个对象。

我可以迭代每个对象,调用方法,并捕获一个异常,但我不知道如何不断调用它上面的方法并继续捕获异常。

java loops try-catch try-catch-finally
4个回答
6
投票

这与其他答案类似,但没有旗帜,这对我来说似乎很混乱。我不太明白这个问题,所以我只是把它扔出去,以防它有用。

for (Item item : items) {
  while (true) {
    try {
      item.doSomething();
      break;
    } catch (MyException ex) {
      log.warn("Something failed.", ex);
    }
  }
}

这种方法取决于未标记的break语句的操作,该语句突然完成,然后通常退出封闭的while语句。


基于后续的评论,我认为当声明由方法抛出多个异常时,它有什么意思。

每次调用方法都可以通过抛出一个异常来终止。你不能以某种方式恢复它停止的调用,并处理后续的异常。

因此,如果方法抛出多个异常,请捕获一个共同的祖先,然后继续前进。例如,如果一个方法抛出java.io.EOFExceptionjava.nio.channels.ClosedChannelException,你可以简单地捕获java.io.IOException,因为它是一个共同的祖先。 (你也可以出于同样的原因捕捉java.lang.Exceptionjava.lang.Throwable。)在相同条件下再次调用该方法不会让你更进一步。

如果要尝试在每个对象上调用该方法,即使某些对象失败,也请使用:

for (Item item : items) {
  try {
    item.doSomething();
  } catch (Exception ex) { /* This could be any common ancestor. */
    log.warn("Something failed.", ex);
  }
}

2
投票

如果你正在谈论处理一个会引发多个异常的单个方法调用,那么就无法完成 - 无论你多少次调用该方法,它都会继续抛出第一个异常。你不能回到这个方法并继续从那里跑;在抛出一个例外之后,一切都结束了。

但是,如果您正在讨论的方法有时会引发异常,有时则不会,请尝试以下方法:

boolean thrown = false;
do {
    try {
        thrown = false;
        method();
    }
    catch (Exception e) {
        thrown = true;
        // Handle as you like
    }
} (while thrown);

0
投票

这就是我的理解。

你有一个对象的方法,可能会抛出许多例外。

你想要做的是抓住它们并继续列表中的下一个对象。

那是对的吗?

那么,那将是:

for( YourObject o : yourList ) {
    try {
       o.thatMethod();//invoke that risky method 
    } catch( SomeExceptionClass sec ) {
       // Do something with that exception
    } catch( SomeOtherExceptionClass soec ) {
       // Do something with that exception  
    } catch( YetAnotherxceptionClass yaec ) {
       // Do something with that exception
    } catch( OtherUnRelatedException oue ) {
       // Do something with that exception
    }
}

执行此操作时,如果thatMethod()的调用抛出异常并且catch部分中列出了该异常,则执行流程将跳转到该异常,然后它将继续正常流程(这是for循环并将继续下一个对象)

我希望这是需要的。有关更多信息,请参阅Java教程部分The catch block中的Essential classes


0
投票

我假设您正在尝试对列表中的项执行某种验证,其中通过抛出异常来报告验证错误。我还假设您正在尝试收集所有验证错误。

简单的答案是使用这种方法无法解决这个问题。要了解原因,请看一下:

boolean exceptionCaught = false;
do {
    try {
        item.doSomething();
    } catch (MyException e) {
        exceptionCaught = true;
    }
} while (exceptionCaught);

这会失败,因为每次调用item.doSomething()时都会在完全相同的位置抛出异常。最终结果是无限循环。

使用此方法可以做的最好的事情是捕获列表中每个item的第一个例外。

那么你怎么能实现你想要实现的目标呢?答案是您必须更改验证代码以使用其他方式报告错误而不是抛出异常。例如,您可以更改:

class Item {
    ...
    void validate() {
        if (noHat) {
            throw new MyException("bad hat");
        }
        if (noPants) {
            throw new MyException("world-wide pants");
        }
    }
}

这样的事情:

class Item {
    ...
    void isValid(List<MyException> errors) {
        boolean ok = true;
        if (noHat) {
            errors.add(new MyException("bad hat"));
            ok = false;
        }
        if (noPants) {
            errors.add(new MyException("world-wide pants"));
            ok = false;
        }
        return ok;
    }
}

凌乱啊!您可以通过各种方式对此进行加糖,但这种错误报告方式总是会变得更加复杂。但我认为没有一种实用的方法来避免混乱并捕获所有验证错误。

© www.soinside.com 2019 - 2024. All rights reserved.