循环在遇到返回语句后仍然继续执行。

huangapple go评论78阅读模式
英文:

Loop continuing even after hitting return statement

问题

我有以下方法,我想不断检查嵌套异常是否与IndexOutOfBoundsException匹配,除非嵌套异常与先前的异常相同。

它似乎在我的测试中表现得很正确,第一个异常是NullPointerException类型,因此继续进行下一个。下一个异常是预期的IndexOutOfBoundsException。

当这种情况发生时,我希望返回true,这会让我跳出循环。看起来正在按预期进行,我确实到达'return true'。但在那之后,循环仍然继续进行。

我漏掉了什么?即使在返回true之后,它是如何继续进行的?

public boolean test(Throwable throwable) {
    do {
        if(throwable instanceof IndexOutOfBoundsException) {
            return true; // 我确实到达这里,因此期望跳出循环和该方法。
        }
        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));
}
英文:

I have the following method where I wan to keep checking if a nested exception matches an IndexOutOfBoundsException unless the nested exception is the same as the previous one.

It seems to do the right thing where in my test, the first exception
is of type NullPointerException thus moving on to the next. The next exception is as expected, an IndexOutOfBoundsException.

When this happens I want to return true which I expect to break me out of the loop.
It seems to be happening as expected where I do land on 'return true'. But after that, the loop keeps going.

What am I missing. How is it keeping on going even after returning true?

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;
}

The test against it simulating nested exception.

@Test
void testWithNestedException() {
    NullPointerException nullPointerException = new NullPointerException();
    IndexOutOfBoundsException indexOutOfBoundsException = new IndexOutOfBoundsException();
    Throwable nestedException = nullPointerException.initCause(indexOutOfBoundsException);
    assertTrue(someClass.test(nestedException));
}

答案1

得分: 4

你正在将递归与循环混合在一起。在这里,一个简单的循环,更新被测试异常的操作,应该可以解决问题:

public boolean test(Throwable throwable) {
    Throwable t = throwable;
    do {
        if (throwable instanceof IndexOutOfBoundsException) {
            return true;
        }
        t = t.getCause();
    } while (t.getCause() != t);

    return false;
}
英文:

You are mixing recursion with looping. Here, a simple loop that updates the exception being tested should do the trick:

public boolean test(Throwable throwable) {
    Throwable t = throwable;
    do {
        if (throwable instanceof IndexOutOfBoundsException) {
            return true;
        }
        t = t.getCause();
    } while (t.getCause() != t);

    return false;
}

答案2

得分: 2

你正在通过这个调用创建递归,并且没有使用这个调用的返回代码。

this.test(throwable.getCause());

我认为你想要这样做:

throwable = throwable.getCause();
英文:

You are creating recursion with this call and don't use the return code from this call.

this.test(throwable.getCause());

I think you wanted to do:

throwable = throwable.getCause();

答案3

得分: 2

正如 @Mureinik 指出的,你在混合使用递归和迭代,并且两者都没有正确实现。一个(正确的)递归版本如下:

public boolean test(Throwable throwable) {
    if (throwable == null) {
        return false;
    } else if (throwable instanceof IndexOutOfBoundsException) {
        return true;
    } else {
        return test(throwable.getCause());
    }
}

在我看来,递归版本比迭代版本更容易理解,但其他人可能持不同意见。

对于递归版本,存在理论问题,即足够深层嵌套的异常可能会导致堆栈溢出。在实践中使其发生需要编写一些相当假设性的(即不现实的)代码,因此可以安全地忽略这一点。

英文:

As @Mureinik points out, you are mixing recursion and iteration and doing neither correctly. A (correct) recursive version would be:

public boolean test(Throwable throwable) {
    if (throwable == null) {
        return false;
    } else if (throwable instanceof IndexOutOfBoundsException) {
        return true;
    } else {
        return test(throwable.getCause());
    }
} 

In my opinion, a recursive version is easier to understand than an iterative one, but others may disagree.

With the recursive version, there is the theoretical problem that sufficiently deeply nested exceptions could lead to a stack overflow. Getting that to happen in practice would require some rather contrived (i.e. unrealistic) code, so it should be safe to ignore this.

huangapple
  • 本文由 发表于 2020年8月15日 19:36:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/63425586.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定