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

}
Chris Martin
  • 30,334
  • 10
  • 78
  • 137
Aaron
  • 11,239
  • 18
  • 58
  • 73
  • 4
    See this question: http://stackoverflow.com/questions/7101992/why-do-we-usually-use-not-what-is-the-difference – Eng.Fouad Jan 06 '12 at 15:07
  • Set B doesn't use logical operators. These use the bitwise operators which compare each bit of the operands. – NomadMaker Mar 01 '21 at 18:50

10 Answers10

293

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.

VLAZ
  • 26,331
  • 9
  • 49
  • 67
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • 13
    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. – Stormcloud Sep 04 '15 at 10:26
  • 13
    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. – A myth Oct 30 '15 at 18:05
  • 2
    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. – mckenzm Aug 05 '19 at 04:28
  • @mckenzm What is the difference between evaluated and executed? – Kronen May 11 '20 at 11:37
  • @Kronen 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. – mckenzm May 11 '20 at 20:37
  • @Kronen 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. – Bohemian May 11 '20 at 22:08
  • 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. – Collin Alpert Feb 11 '21 at 09:16
  • @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`. – Bohemian Feb 11 '21 at 13:15
  • @CollinAlpert The middle true is not evaluated, as the && short circuits. – Donnie Feb 16 '21 at 23:05
  • In short, `false && true || true` is `(false && true) || true` – Scar Jul 26 '21 at 12:50
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)
afrischke
  • 3,836
  • 17
  • 30
  • Please specify that this is the case for `&&`, `||` works differently and will cease evaluation on the first operand which returns true ;) – fge Jan 06 '12 at 15:12
  • 2
    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 ;) – fge Jan 06 '12 at 15:30
  • @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. – afrischke Jan 06 '12 at 15:39
  • No worries, knowledge has no value if it is not shared. – fge Jan 06 '12 at 15:50
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).

CodePoet
  • 704
  • 5
  • 20
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
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()) { }
}
Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
  • -1 Your answer suggests that `&` is *only* a bitwise operator, but that is not true. It is *also* a boolean "or" operator. – Bohemian Jan 06 '12 at 15:20
  • @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. – Bhesh Gurung Jan 06 '12 at 15:27
  • Sorry - I meant boolean `AND`, not `OR`! ie `true & false` is valid syntax. -1 removed :) – Bohemian Jan 06 '12 at 23:23
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.

Bhushan
  • 18,329
  • 31
  • 104
  • 137
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.

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
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.

4444
  • 3,541
  • 10
  • 32
  • 43
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.

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

Nitesh Verma
  • 1,795
  • 4
  • 27
  • 46
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

Doktor
  • 73
  • 2
  • 6