基本上遍历一个列表,
- 在第一个对象上调用方法
- 捕获第一个异常(如果有);如果没有更多的异常要捕获,则正常返回。否则,继续调用方法,直到所有异常都被捕获。
- 移动到下一个对象。
我可以遍历每个对象,调用方法并捕获一个异常,但我不知道如何持续调用它的方法并继续捕获异常。
基本上遍历一个列表,
- 在第一个对象上调用方法
- 捕获第一个异常(如果有);如果没有更多的异常要捕获,则正常返回。否则,继续调用方法,直到所有异常都被捕获。
- 移动到下一个对象。
我可以遍历每个对象,调用方法并捕获一个异常,但我不知道如何持续调用它的方法并继续捕获异常。
这类似于其他答案,但没有标志,这对我来说似乎很混乱。不过我不太明白这个问题,所以我只是把它扔在那里以防万一它有用。
for (Item item : items) {
while (true) {
try {
item.doSomething();
break;
} catch (MyException ex) {
log.warn("Something failed.", ex);
}
}
}
这种方法取决于未标记break
语句的操作,它突然完成,然后while
正常退出封闭语句。
根据随后的评论,我认为当声明一个方法抛出多个异常时,这意味着什么有些混淆。
方法的每次调用都可以仅通过抛出一个异常来终止。您无法以某种方式从中断处恢复调用,并处理后续异常。
因此,如果一个方法抛出多个异常,则捕获一个共同的祖先,然后继续。例如,如果一个方法抛出java.io.EOFException
or java.nio.channels.ClosedChannelException
,你可以简单地捕捉,java.io.IOException
因为它是一个共同的祖先。(您也可以 catchjava.lang.Exception
或java.lang.Throwable
出于相同的原因。)在相同条件下再次调用该方法不会让您更进一步。
如果你想尝试调用每个对象的方法,即使有些失败,使用这个:
for (Item item : items) {
try {
item.doSomething();
} catch (Exception ex) { /* This could be any common ancestor. */
log.warn("Something failed.", ex);
}
}
如果您正在谈论处理将引发多个异常的单个方法调用,则无法完成 - 无论您调用该方法多少次,它都会继续抛出第一个异常。你不能回到方法并从那里继续运行;抛出一个异常后,一切都结束了。
但是,如果您正在谈论一种有时会抛出异常而有时不会抛出异常的方法,请尝试以下操作:
boolean thrown = false;
do {
try {
thrown = false;
method();
}
catch (Exception e) {
thrown = true;
// Handle as you like
}
} (while thrown);
我假设您正在尝试对列表中的项目执行某种验证,其中通过抛出异常来报告验证错误。我还假设您正在尝试收集所有验证错误。
简单的答案是使用这种方法无法解决这个问题。要了解原因,请查看以下内容:
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;
}
}
乱七八糟的!您可以通过各种方式对此进行加糖,但这种错误报告方式总是会更加复杂。但我认为没有一种实用的方法可以避免混乱并捕获所有验证错误。
这是我的理解。
你有一个对象的方法,它可能会抛出一些异常。
您想要做的是将它们全部捕获并继续列表中的下一个对象。
那是对的吗?
所以,那将是:
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
循环并将继续下一个对象)