Java logical operator short-circuiting
Asked Answered
I

10

131

Which set is short-circuiting, and what exactly does it mean that the complex conditional expression is short-circuiting?

public static void main(String[] args) {
  int x, y, z;

  x = 10;
  y = 20;
  z = 30;

  // T T
  // T F
  // F T
  // F F

  //SET A
  boolean a = (x < z) && (x == x);
  boolean b = (x < z) && (x == z);
  boolean c = (x == z) && (x < z);
  boolean d = (x == z) && (x > z);
  //SET B    
  boolean aa = (x < z) & (x == x);
  boolean bb = (x < z) & (x == z);
  boolean cc = (x == z) & (x < z);
  boolean dd = (x == z) & (x > z);

}
Impale answered 6/1, 2012 at 15:6 Comment(2)
See this question: #7102492Placeman
Set B doesn't use logical operators. These use the bitwise operators which compare each bit of the operands.Mann
S
298

The && and || operators "short-circuit", meaning they don't evaluate the right-hand side if it isn't necessary.

The & and | operators, when used as logical operators, always evaluate both sides.

There is only one case of short-circuiting for each operator, and they are:

  • false && ... - it is not necessary to know what the right-hand side is because the result can only be false regardless of the value there
  • true || ... - it is not necessary to know what the right-hand side is because the result can only be true regardless of the value there

Let's compare the behaviour in a simple example:

public boolean longerThan(String input, int length) {
    return input != null && input.length() > length;
}

public boolean longerThan(String input, int length) {
    return input != null & input.length() > length;
}

The 2nd version uses the non-short-circuiting operator & and will throw a NullPointerException if input is null, but the 1st version will return false without an exception.

Shellacking answered 6/1, 2012 at 15:10 Comment(10)
I'd just like to extend this answer a little. The &= operator is a shorthand for x = x & expression, and therefore is does NOT short circuit. The same is true of the |= operator.Repentant
One thing I would like to highlight, | and & are binary operators,while && and || are conditional (logical) operators. | and & work on more than just booleans,while && and || work only on booleans.Mariandi
Not only do they not evaluate the expression on the right hand side, the code is not executed for there to be anything to evaluate. This is a critical point of understanding if a side effect would otherwise be produced.Disillusion
@Disillusion What is the difference between evaluated and executed?Rodina
@Rodina Execution may result in more than the evaluation, and produce a side effect, such as an exception or a delay, I will pay not relevant to this example.Disillusion
@Rodina In this context, there is no difference. In order to be evaluated it must be executed. If something doesn’t need evaluating it isn’t executed.Shellacking
I have a question regarding your statement that false && ... does not get evaluated because the result can only be false. Consider the statement false && true || true. This is evaluated to true.Kendrickkendricks
@CollinAlpert anything || true is true. The operator && has greater precedence than || so it’s evaluated first, thus false && true || true becomes false || true, which is (as you found) true. It remains a fact that false && true is false.Shellacking
@CollinAlpert The middle true is not evaluated, as the && short circuits.Longfellow
In short, false && true || true is (false && true) || trueUnmade
E
10

SET A uses short-circuiting boolean operators.

What 'short-circuiting' means in the context of boolean operators is that for a set of booleans b1, b2, ..., bn, the short circuit versions will cease evaluation as soon as the first of these booleans is true (||) or false (&&).

For example:

// 2 == 2 will never get evaluated because it is already clear from evaluating
// 1 != 1 that the result will be false.
(1 != 1) && (2 == 2)

// 2 != 2 will never get evaluated because it is already clear from evaluating
// 1 == 1 that the result will be true.
(1 == 1) || (2 != 2)
Erland answered 6/1, 2012 at 15:9 Comment(4)
Please specify that this is the case for &&, || works differently and will cease evaluation on the first operand which returns true ;)Counterglow
In fact, to be really complete, all of &&, ||, & and | evaluate left to right. For a set of booleans b1, b2, ..., bn, the short circuit versions will cease evaluation when the first of these booleans is true (||) or false (&&). Bah, the principle is there ;)Counterglow
@fge: Yes, you are right of course. Your definition is exacter than mine. I have updated my answer with the sentence in your comment. I hope you don't mind.Erland
No worries, knowledge has no value if it is not shared.Counterglow
G
4

In plain terms, short-circuiting means stopping evaluation once you know that the answer can no longer change. For example, if you are evaluating a chain of logical ANDs and you discover a FALSE in the middle of that chain, you know the result is going to be false, no matter what are the values of the rest of the expressions in the chain. Same goes for a chain of ORs: once you discover a TRUE, you know the answer right away, and so you can skip evaluating the rest of the expressions.

You indicate to Java that you want short-circuiting by using && instead of & and || instead of |. The first set in your post is short-circuiting.

Note that this is more than an attempt at saving a few CPU cycles: in expressions like this

if (mystring != null && mystring.indexOf('+') > 0) {
    ...
}

short-circuiting means a difference between correct operation and a crash (in the case where mystring is null).

Grandaunt answered 6/1, 2012 at 15:10 Comment(0)
A
4
boolean a = (x < z) && (x == x);

This kind will short-circuit, meaning if (x < z) evaluates to false then the latter is not evaluated, a will be false, otherwise && will also evaluate (x == x).

& is a bitwise operator, but also a boolean AND operator which does not short-circuit.

You can test them by something as follows (see how many times the method is called in each case):

public static boolean getFalse() {
    System.out.println("Method");
    return false;
}

public static void main(String[] args) {
    if(getFalse() && getFalse()) { }        
    System.out.println("=============================");        
    if(getFalse() & getFalse()) { }
}
Archiplasm answered 6/1, 2012 at 15:10 Comment(3)
-1 Your answer suggests that & is only a bitwise operator, but that is not true. It is also a boolean "or" operator.Shellacking
@Bohemian: Thanks for the heads up. true & false evaluates to false. Can you please explain this "boolean "or" operator"? May be I am not getting what you are trying to say.Archiplasm
Sorry - I meant boolean AND, not OR! ie true & false is valid syntax. -1 removed :)Shellacking
K
4

Short circuiting means the second operator will not be checked if the first operator decides the final outcome.

E.g. Expression is: True || False

In case of ||, all we need is one of the side to be True. So if the left hand side is true, there is no point in checking the right hand side, and hence that will not be checked at all.

Similarly, False && True

In case of &&, we need both sides to be True. So if the left hand side is False, there is no point in checking the right hand side, the answer has to be False. And hence that will not be checked at all.

Kuroshio answered 6/1, 2012 at 15:10 Comment(0)
R
3

There are a couple of differences between the & and && operators. The same differences apply to | and ||. The most important thing to keep in mind is that && is a logical operator that only applies to boolean operands, while & is a bitwise operator that applies to integer types as well as booleans.

With a logical operation, you can do short circuiting because in certain cases (like the first operand of && being false, or the first operand of || being true), you do not need to evaluate the rest of the expression. This is very useful for doing things like checking for null before accessing a filed or method, and checking for potential zeros before dividing by them. For a complex expression, each part of the expression is evaluated recursively in the same manner. For example, in the following case:

(7 == 8) || ((1 == 3) && (4 == 4))

Only the emphasized portions will evaluated. To compute the ||, first check if 7 == 8 is true. If it were, the right hand side would be skipped entirely. The right hand side only checks if 1 == 3 is false. Since it is, 4 == 4 does not need to be checked, and the whole expression evaluates to false. If the left hand side were true, e.g. 7 == 7 instead of 7 == 8, the entire right hand side would be skipped because the whole || expression would be true regardless.

With a bitwise operation, you need to evaluate all the operands because you are really just combining the bits. Booleans are effectively a one-bit integer in Java (regardless of how the internals work out), and it is just a coincidence that you can do short circuiting for bitwise operators in that one special case. The reason that you can not short-circuit a general integer & or | operation is that some bits may be on and some may be off in either operand. Something like 1 & 2 yields zero, but you have no way of knowing that without evaluating both operands.

Runner answered 5/2, 2018 at 17:22 Comment(0)
G
2

Java provides two interesting Boolean operators not found in most other computer languages. These secondary versions of AND and OR are known as short-circuit logical operators. As you can see from the preceding table, the OR operator results in true when A is true, no matter what B is.

Similarly, the AND operator results in false when A is false, no matter what B is. If you use the || and && forms, rather than the | and & forms of these operators, Java will not bother to evaluate the right-hand operand alone. This is very useful when the right-hand operand depends on the left one being true or false in order to function properly.

For example, the following code fragment shows how you can take advantage of short-circuit logical evaluation to be sure that a division operation will be valid before evaluating it:

if ( denom != 0 && num / denom >10)

Since the short-circuit form of AND (&&) is used, there is no risk of causing a run-time exception from dividing by zero. If this line of code were written using the single & version of AND, both sides would have to be evaluated, causing a run-time exception when denom is zero.

It is standard practice to use the short-circuit forms of AND and OR in cases involving Boolean logic, leaving the single-character versions exclusively for bitwise operations. However, there are exceptions to this rule. For example, consider the following statement:

 if ( c==1 & e++ < 100 ) d = 100;

Here, using a single & ensures that the increment operation will be applied to e whether c is equal to 1 or not.

Gaskins answered 24/7, 2013 at 19:7 Comment(0)
P
2

Logical OR :- returns true if at least one of the operands evaluate to true. Both operands are evaluated before apply the OR operator.

Short Circuit OR :- if left hand side operand returns true, it returns true without evaluating the right hand side operand.

Paedogenesis answered 9/4, 2016 at 16:25 Comment(0)
B
1
if(demon!=0&& num/demon>10)

Since the short-circuit form of AND(&&) is used, there is no risk of causing a run-time exception when demon is zero.

Ref. Java 2 Fifth Edition by Herbert Schildt

Barger answered 12/7, 2013 at 5:7 Comment(0)
M
1

Document from docs.oracle

As logical expressions are evaluated left to right, they are tested for possible “short-circuit” evaluation using these rules:

false && anything is short-circuit evaluated to false.

true || anything is short-circuit evaluated to true.

The rules of logic guarantee that these evaluations are always correct. Note that the anything part of the above expressions is not evaluated, so any side effects of doing so do not take effect.

https://docs.oracle.com/cd/E57185_01/HIRUG/ch31s05s01.html

Mind answered 1/3, 2021 at 18:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.