In Java, What Are the Boolean "Order of Operations"

In Java, what are the boolean order of operations?

The Java Tutorials has a list illustrating operator precedence. The equality operators will be evaluated first, then &&, then ||. Parentheses will be evaluated before anything else, so adding them can change the order. This is usually pretty much the same from language to language, but it's always a good idea to double check.

It's the small variations in behavior that you're not expecting that can cause you to spend an entire day debugging, so it's a good idea to put the parentheses in place so you're sure what the order of evaluation will be.

Order of Operations with Logic in Java Confused

res = a++ == 2 || --a == 2 && --a == 2 (res is true)

1. a++ (post-increment, no) -> a = a + 1 -> it's still 2 -> when true -> it becomes 3
2. --a (pre-increment, right to left) -> a - 1 = a -> 1
3. --a (pre-increment, right to left) -> a - 1 = a -> 0 (its because of logical and, it never execute this part)
4. == (equality, left to right) -> 2 == 2 || 1 == 2 && 0 == 2 -> true || false && false
5. && (logical and, left to right) -> false -> no more steps
6. || (logical or, left to right) -> true -> go to 1.

// so take 3
// moral of the story is always use paranthesis
// op is correct for short-circuit

Listing the precedence order of the Boolean operators on java

Operator precedence is merely the order in which operations are applied. For example, consider the following mathematical statement:

10 + 6 / 2

Well, (10 + 6) / 2 = 16 / 2 = 8, but 10 + (6 / 2) = 10 + 3 = 13, so clearly it matters what order you perform the operations in. Mathematically, which one of these answers is correct? If you were asked this question on an exam, which answer should you put down? Operator precedence tells you that.

The question is asking you to do something similar for Boolean operators.

Try the following program:

public class HelloWorld {

public static void main(String []args){
System.out.println(true || true && false);

System.out.println(true && true || false);
}
}

It turns out that both of them are true.

In order to learn more about this, you can experiment with parentheses to see how this changes the truth value of the statements. For example,

System.out.println((true || true) && false);

is false. Contrast that with the fact that

System.out.println(true || true && false);

is true. What does this tell you about the order in which Java is performing the operations? Well, the way that I wrote the parenthesis changed the result, so clearly that's not right. You can infer from this that Java must be doing the parentheses "the other way":

System.out.println(true || (true && false));

If you check the chart in @Sand's answer, && does, in fact, have higher precedence than ||, so this operation is applied first. This is exactly what we see here.

Does the order of operands in a boolean matter?

Yes, it does matter and

... the Java language does not define order of evaluation

is not true. The arguments are evaluated from left to right, so an expression like s != null && s.length() > 10 will never throw a NullPointerException.

See 15.7 Expressions - Evaluation Order in the Java Language Specification.

Boolean operators precedence

I googled and found out this which says that some languages like APL and SmallTalk do not have operator precedence rules and they strictly evaluate expressions from left to right/left to right.

However,relative order of precedence followed is NOT > XOR > AND > OR in most of the languages especially those derived from C

Logical operator precedence in Java

"These operators have different precedence, with & having the highest
precedence and | the lowest precedence".

Just because they have higher precedence, doesn't mean their operands will be evaluated first.

This

boolean bool = isTrue1() | isFalse1() & isFalse2() ;

becomes equivalent to

boolean bool = isTrue1() | ( isFalse1() & isFalse2() ) ;

That's all precedence is.

As the Java Language Specification says, operator operands are evaluated left to right.

The Java programming language guarantees that the operands of
operators appear to be evaluated in a specific evaluation order,
namely, from left to right.

Boolean expression order of evaluation in Java?

However, I know some that some compilers will exit the boolean expression entirely if the first condition fails. Is this true with Java?

Yes, that is known as Short-Circuit evaluation.Operators like && and || are operators that perform such operations.

Or is the order of evaluation not guaranteed?

No,the order of evaluation is guaranteed(from left to right)

Confusing example about '&&' and '||' precedence

The expression is short-circuiting. From the link:

when the first argument of the AND function evaluates to false, the overall value must be false; and when the first argument of the OR function evaluates to true, the overall value must be true.

It sees that the rest of the condition doesn't matter because one of the operands of || is already true (10 < 20). If one of the operands is true, then no matter what the rest of the condition is, it's true.

You may use bitwise & and | to prevent this.



But, the ( expr2 && expr3 ) should be evaluated before expr1, no ?

No. You have to separate concepts of precedence and evaluation order.

  • Precedence: Dictates the parenthesization of an expression, not the order in which an expression is evaluated. For an example:

      true || false && false

    Is parenthesized to this because && has higher precedence than ||:

      true || (false && false)

    This does not mean that things in parentheses is evaluated first in Java's case. Precedence just clarifies what the operands of an operator are, in this case false and false, where as in this case:

      (true || false) && (false || false)

    The operands for && are true and false, not false and false.

  • Evaluation Order: Describes in what order each operand is evaluated and operator is applied and is sometimes language specific. This dictates how an expression is evaluated, unlike precedence.

In this case, your example:

true || false && false

As established earlier, becomes this due to precedence:

true || (false && false)

But Java, unlike C++, JavaScript, or a number of other languages has a strictly left to right evaluation. Per the Java Language Specification:

15.7. Evaluation Order

The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.

15.7.1. Evaluate Left-Hand Operand First

The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.

So, when you have:

true || (false && false)

Java first evaluates the left operand which turns out to be true. Then the whole condition short circuits. The right operand of || in the parentheses is never evaluated at all. The same goes for your other example:

a1 < a2 || (++a1 > a2 && ++a2 < a1)
^^^^^^^^^^^^^^^^^^^^^^^^
Step 0, precedence and parenthesization


a1 < a2 || (++a1 > a2 && ++a2 < a1)
^^^^^^^
Step 1, left operand evaluated, variables resolved to values 10 and 20, condition is true


true || (++a1 > a2 && ++a2 < a1)
^^^^
Step 2, short circuits, left operand is not evaluated

Take another more complex example:

false || false || true && (false || true) || false

Due to precedence, it becomes:

false || false || (true && (false || true)) || false

Then, evaluation begins, left to right:

false || false || (true && (false || true)) || false
^^^^^^^^^^^^^^
Step 1, false || false, does not short circuit, right operand is evaluated, is false


false || (true && (false || true)) || false
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Step 2, false || (true && (false || true)), does not short circuit, right operand is evaluated
Step 2A, (true && (false || true)), does not short circuit, right operand is evaluated
Step 2B, (false || true), does not short circuit, right operand is evaluated, is true
Step 2C, (true && true), does not short circuit, right operand is evaluated, is true
Step 2D, false || true, does not short circuit, right operand is evaluated, is true


true || false
^^^^
Step 3, true || false short circuits, right operand is not evaluated, is true

Thus the whole expression evaluates to true. The whole expression was evaluated left to right the whole way through. Precedence only dictated the operands of an operator via parenthesization, not the evaluation order.

Further reading at Eric Lippert's explanatory article on precedence vs associativity vs evaluation order as mentioned by Daniel Pryden, it clears up a lot of the confusion.

The main takeaway is that precedence does not dictate in what an expression is evaluated. It only dictates how an expression should be parenthesized. Evaluation order, on the other hand, tells us exactly how an expression is evaluated, and in Java's case is always left to right.



Related Topics



Leave a reply



Submit