jtomaszk
jtomaszk

Reputation: 11201

java unexpected and unaccountable break of loop

Let compare this two methods...

Case 1: function working correctly

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

Output

It give me following expected output (I have cuted newlines):

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

Case 2: function that makes unexpected break

But this method

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

Output

Give me only this output, the loop had to be broke! There was no exception!

0 ret false

Could anybody explain why in this case loop was terminated without any error?

Rest of code

Here are my fooIf and fooMethod functions:

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

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

Upvotes: 1

Views: 162

Answers (3)

leigero
leigero

Reputation: 3283

your statement ret = ret && fooMethod(i); is setting ret = to false because fooMethod(i), when i = 0 (first time through the loop) returns false.

fooMethod(i) prints 0 to the screen, returns a false value and sets ret = ret && fooMethod(i) which is the same as saying 'ret = true && false` which returns false.

Once ret is false after the first iteration of the loop the program needs not run the fooMethod because regardless of what comes back the result will be false, because ret is already false:

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

this means your loop runs the first time, printing out 0 and every iteration thereafter fails to change the value of ret. Once it's done it prints ret and false

Upvotes: 1

das Keks
das Keks

Reputation: 3941

Your function actually does not break, fooMethod(i) is just not called anymore because && is short circuit.

That means that the second expression in only evaluated if needed. If you have false && x you do not have to know what value x has because the result will always be false.

In your case ret turns to false after the first iteration. Therefor the return value of fooMethod(i) is irrelevant and the method is not called.

Try to change ret = ret && fooMethod(i); to ret = ret & fooMethod(i);. The result will be the same as in your first case.

Upvotes: 1

Martijn Courteaux
Martijn Courteaux

Reputation: 68887

&& is short circuit. That means that if in a && b, a evaluates to false, b isn't evaluated anymore. So, the loop doesn't break. What is happening is that fooMethod is not called, because ret gets false after the first iteration.

Upvotes: 9

Related Questions