即使在命中 return 语句后循环仍在继续
Loop continuing even after hitting return statement
我有以下方法,我想继续检查嵌套异常是否与 IndexOutOfBoundsException 匹配,除非嵌套异常与前一个异常相同。
在我的测试中,第一个异常似乎做了正确的事情
是 NullPointerException 类型,因此继续下一个。下一个异常是预期的,一个 IndexOutOfBoundsException。
发生这种情况时,我希望 return 为真,我希望这能让我摆脱困境。
它似乎在我登陆 'return true' 的地方按预期发生。但在那之后,循环继续。
我错过了什么。即使在 return 为真之后,它如何继续运行?
public boolean test(Throwable throwable) {
do {
if(throwable instanceof IndexOutOfBoundsException) {
return true; // I do land here thus expecting to get out of loop and this method.
}
this.test(throwable.getCause());
} while (throwable.getCause() != throwable);
return false;
}
模拟嵌套异常的测试。
@Test
void testWithNestedException() {
NullPointerException nullPointerException = new NullPointerException();
IndexOutOfBoundsException indexOutOfBoundsException = new IndexOutOfBoundsException();
Throwable nestedException = nullPointerException.initCause(indexOutOfBoundsException);
assertTrue(someClass.test(nestedException));
}
您将递归与循环混合在一起。在这里,更新正在测试的异常的简单循环应该可以解决问题:
public boolean test(Throwable throwable) {
Throwable t = throwable;
do {
if (throwable instanceof IndexOutOfBoundsException) {
return true;
}
t = t.getCause();
} while (t.getCause() != t);
return false;
}
您正在使用此调用创建递归并且不使用此调用中的 return 代码。
this.test(throwable.getCause());
我想你想做的是:
throwable = throwable.getCause();
正如@Mureinik 指出的那样,您正在混合递归和迭代,并且两者都不正确。一个(正确的)递归版本是:
public boolean test(Throwable throwable) {
if (throwable == null) {
return false;
} else if (throwable instanceof IndexOutOfBoundsException) {
return true;
} else {
return test(throwable.getCause());
}
}
在我看来,递归版本比迭代版本更容易理解,但其他人可能不同意。
对于递归版本,存在足够深的嵌套异常可能导致堆栈溢出的理论问题。在实践中实现这一点需要一些相当人为的(即不切实际的)代码,因此忽略它应该是安全的。
我有以下方法,我想继续检查嵌套异常是否与 IndexOutOfBoundsException 匹配,除非嵌套异常与前一个异常相同。
在我的测试中,第一个异常似乎做了正确的事情 是 NullPointerException 类型,因此继续下一个。下一个异常是预期的,一个 IndexOutOfBoundsException。
发生这种情况时,我希望 return 为真,我希望这能让我摆脱困境。 它似乎在我登陆 'return true' 的地方按预期发生。但在那之后,循环继续。
我错过了什么。即使在 return 为真之后,它如何继续运行?
public boolean test(Throwable throwable) {
do {
if(throwable instanceof IndexOutOfBoundsException) {
return true; // I do land here thus expecting to get out of loop and this method.
}
this.test(throwable.getCause());
} while (throwable.getCause() != throwable);
return false;
}
模拟嵌套异常的测试。
@Test
void testWithNestedException() {
NullPointerException nullPointerException = new NullPointerException();
IndexOutOfBoundsException indexOutOfBoundsException = new IndexOutOfBoundsException();
Throwable nestedException = nullPointerException.initCause(indexOutOfBoundsException);
assertTrue(someClass.test(nestedException));
}
您将递归与循环混合在一起。在这里,更新正在测试的异常的简单循环应该可以解决问题:
public boolean test(Throwable throwable) {
Throwable t = throwable;
do {
if (throwable instanceof IndexOutOfBoundsException) {
return true;
}
t = t.getCause();
} while (t.getCause() != t);
return false;
}
您正在使用此调用创建递归并且不使用此调用中的 return 代码。
this.test(throwable.getCause());
我想你想做的是:
throwable = throwable.getCause();
正如@Mureinik 指出的那样,您正在混合递归和迭代,并且两者都不正确。一个(正确的)递归版本是:
public boolean test(Throwable throwable) {
if (throwable == null) {
return false;
} else if (throwable instanceof IndexOutOfBoundsException) {
return true;
} else {
return test(throwable.getCause());
}
}
在我看来,递归版本比迭代版本更容易理解,但其他人可能不同意。
对于递归版本,存在足够深的嵌套异常可能导致堆栈溢出的理论问题。在实践中实现这一点需要一些相当人为的(即不切实际的)代码,因此忽略它应该是安全的。