开发者

Why is the output different in case of &&, &, ||?

开发者 https://www.devze.com 2023-01-10 15:36 出处:网络
Here is the code segments Can you explain why outputs are varying 1) public static ShortCkt { public static void main(String args[]) {

Here is the code segments

Can you explain why outputs are varying

1)

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t && ((i++) == 0));
        b = (f && ((i+=2) > 0));
        System.out.println(i);      
    }
}

output in this case is 1

2)

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t & ((i++) == 0));
        b = (f & ((i+=2) > 0));
        Syste开发者_StackOverflowm.out.println(i);      
    }
}

output in this case is 3

3)

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t || ((i++) == 0));
        b = (f || ((i+=2) > 0));
        System.out.println(i);      
    }
}

output in this case is 2

4)

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t | ((i++) == 0));
        b = (f | ((i+=2) > 0));
        System.out.println(i);      
    }
}

output in this case is 3


Why is the output different in case of &&, &, || ?

Just as in C/C++ && is evaluated "lazily" while & is not.

If a is false then a && b will return false without even evaluating b.

Same goes for a || b: If the first operand, a is true, the whole expression is true and the second operand, b is never evaluated. For a | b however, both a and b will be evaluated.

This has consequences if the operand that's not being evaluated when using && (or ||) has side effects, as in your examples.


Side note: Few java-programmers know that ^ (xor) works for booleans as well. (A ^^ version does not exist simply because it would be redundant.)


There are 4 boolean binary operators that we're concerned with here:

  • && is the conditional and operator
    • & is the logical and operator
  • || is the conditional or operator
    • | is the logical or operator

Here's the key point:

  • "conditional" means it short-circuits: it does not evaluate the right operand if it will not affect the result of the operation
  • "logical" does not short-circuit: it evaluates both operands, left first, then right.
  • The result of "and" is true only if both operands are true
    • If the left operand is false, the result is false regardless of right operand
  • The result of "or" is true only if at least one operand is true
    • If the left operand is true, the result is true regardless of right operand

In other words, assuming no exception etc:

  • & and | always evaluate both operands
  • && and || evaluate the right operand conditionally; the right operand is evaluated only if its value could affect the result of the binary operation. That means that the right operand is NOT evaluated when:
    • The left operand of && evaluates to false
      • (because no matter what the right operand evaluates to, the entire expression is false)
    • The left operand of || evaluates to true
      • (because no matter what the right operand evaluates to, the entire expression is true)

References

  • JLS 15.22.2 Boolean Logical Operators &, ^, and |
    • For &, the result value is true if both operand values are true; otherwise, the result is false.
    • For |, the result value is false if both operand values are false; otherwise, the result is true.
  • JLS 15.23 Conditional-And Operator &&
    • The && operator is like &, but evaluates its right-hand operand only if the value of its left-hand operand is true.
  • JLS 15.24 15.24 Conditional-Or Operator ||
    • The || operator is like |, but evaluates its right-hand operand only if the value of its left-hand operand is false.

See also

  • JLS 15.22.1 Integer Bitwise Operators &, ^, and |

Related questions

  • What’s the difference between | and || in Java?
  • Do &= and |= short-circuit in Java? (NO!)
  • Shortcut "or-assignment" (|=) operator in Java
  • Why doesn’t Java have &&= or ||=?


&& and || are the logical AND and OR operators, they always result in a boolean expression. & and | are bitwise AND and OR operators, they do a bitwise comparison of each side. For more information about what those operators do, see this link


This is because && and || are logical operators which a "short circut mechanism". If you use || and the first expression evaluates to true, the second won't be evaluated and hence i will not be udated. & and | are bitwise operators which do bit calculations on the input. These do not have short circut and hence the entire expression is evaluated no matter what.


The & and | operators are bitwise, and thus must have both sides of the expression evaluated before the operator can be used, so in cases 2 and 4 both sides of the operator are always evaluated.

The difference between cases 1 and 3 is based on short-circuit logic.

In case 1 the && operator in the second expression short-circuits as false on the first false, causing the second half of the expression not to be evaluated.

In case 3 the false in the first half of the second expression leads to the evaluation of the second half of the expression, incrementing i. false || expr can only be false if expr is also false (so it must be evaluated).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号