1

让我们比较这两种方法...

案例一:功能正常

public void fooTestOk() {
    boolean ret = true;
    for (int i = 0; i < 10; i++) {
        boolean r;

        if (fooIf(i))
            r = fooMethod(i);
        else 
            r = fooMethod(i);

        ret = ret && r;
    }
    System.out.println("ret "+ret);
}

输出

它给了我以下预期的输出(我已经删除了换行符):

0 1 2 3 4 5 6 7 8 9 ret false

案例 2:导致意外中断的函数

但是这个方法

public void fooTestFail() {
    boolean ret = true;
    for (int i = 0; i < 10; i++) {

        if (fooIf(i))
            ret = ret && fooMethod(i);
        else 
            ret = ret && fooMethod(i);      
    }
    System.out.println("ret "+ret);
}

输出

只给我这个输出,必须打破循环!没有例外!

0 ret false

谁能解释为什么在这种情况下循环被终止而没有任何错误

其余代码

这是我的fooIffooMethod功能:

public boolean fooIf(int i) {
    return i % 2 == 0;
}

public boolean fooMethod(int i) {
    System.out.println(i);
    return i == 5;
}
4

3 回答 3

9

&&是短路。这意味着如果 in a && b,a评估为false,b不再评估。所以,循环不会中断。发生的事情fooMethod是没有调用,因为在第一次迭代之后ret获取。false

于 2013-08-27T12:42:59.697 回答
1

您的函数实际上并没有中断,只是因为短路fooMethod(i)而不再调用。&&

这意味着仅在需要时才评估第二个表达式。如果你有false && x,你不必知道有什么价值x,因为结果总是false

在您的情况下,在第一次迭代后ret转向。false因此, 的返回值fooMethod(i)无关紧要,并且不会调用该方法。

尝试更改ret = ret && fooMethod(i);ret = ret & fooMethod(i);. 结果将与您的第一种情况相同。

于 2013-08-27T12:52:29.460 回答
1

您的语句ret = ret && fooMethod(i);将 ret = 设置为 false,因为 fooMethod(i),当 i = 0(第一次通过循环)返回 false。

fooMethod(i) 将 0 打印到屏幕上,返回一个 false 值并设置ret = ret && fooMethod(i)与返回 false 的 'ret = true && false` 相同。

一旦循环的第一次迭代后 ret 为假,程序就不需要运行 fooMethod,因为无论返回什么结果都将为假,因为 ret 已经为假:

ret = false && //doesn't matter what else, ret is false

这意味着您的循环第一次运行,打印出 0,此后的每次迭代都无法更改 ret 的值。完成后,它会打印 ret 和 false

于 2013-08-27T12:56:04.717 回答