2

Will java actually call all three functions at runtime if one of them does not return true?

Often for debugging purposes, I like to see the result of these conditional checks in the debugger and putting them in one line makes that much more difficult. If there are half a dozen checks, then the code gets to be more unreadable.

boolean result1 = CheckSomething();
boolean result2 = CheckSomethingElse();
boolean result3 = CheckSomeOtherThing();

boolean finalResult = result1 && result2 && result3;

If Java doesn't optimize this conditional at runtime, then better performance should be achieved by writing the code like this at a cost of not being able to easily see the intermediary values in the debugger.

boolean finalResult = CheckSomething() && CheckSomethingElse() && CheckSomeOtherThing();
Mark F
  • 21
  • 1
  • 4
    in your last example if `CheckSomething()` returns false other functions will not be called – maks Nov 17 '16 at 20:59
  • Possible duplicate of [Does Java evaluate remaining conditions after boolean result is known?](http://stackoverflow.com/questions/6352139/does-java-evaluate-remaining-conditions-after-boolean-result-is-known) – matias elgart Nov 17 '16 at 20:59
  • @matiaselgart That would be a different kind of question. He is asking whether the compiler will generate different bytecode, not if the evaulation continues after the result of a boolean operation is known (which it doesn't). – Stefan Nov 17 '16 at 21:01
  • 1
    If any of those functions have side effects, Java is required to perform the side effects in your first code snippet. – user2357112 Nov 17 '16 at 21:02
  • @Stefan - I don't think he's talking about just different _bytecode_, because he's tagged it `jit`. The bytecode is definitely different, but the compiled code certainly may not be. – BeeOnRope Nov 17 '16 at 21:42

3 Answers3

2

You can write this:

boolean result1 = condition1();
boolean result2 = result1 && condition2();
boolean result3 = result2 && condition3();

This allows you to step through each condition, and to see the intermediate results without executing unnecessary code.

You can also set a single breakpoint after the result3 line, which shows you the first result that returned false.

Roland Illig
  • 40,703
  • 10
  • 88
  • 121
  • Or just a single `result` variable. – Andreas Nov 17 '16 at 21:26
  • @Andreas the main reason for this question is to be able to look at the intermediate result. Having only one variable will prevent exactly this. – Roland Illig Nov 18 '16 at 00:06
  • Not really. You see the intermediate results as you *step* through the code. In general, once you step past the end of a variables scope, you lose the ability to see what it was. This is no different. Once you step over the next line, the result of the previous line is no longer available. Sure, separate variables will *extend* the scope of the intermediate values, but reusing a single variable does not *prevent* you from seeing them. – Andreas Nov 18 '16 at 00:14
  • I just realized you may have misunderstood my first comment. I didn't mean to merge the 3 statements into a single statement, I just meant to use a single variable instead of three, i.e. `boolean result = condition1(); result = result && condition2(); result = result && condition3();` – Andreas Nov 18 '16 at 00:22
  • 1
    Using separate variables allows me to just have a single breakpoint, and when I stop there, I can look at all three values and see which condition was the first to return `false`. This is not possible using a single variable. – Roland Illig Nov 18 '16 at 00:51
2

In general your code snippets are not equivalent. The first version must behave as-if all functions are called since you call them unconditionally in your code.

The second version of your code:

boolean finalResult = CheckSomething() && CheckSomethingElse() && CheckSomeOtherThing();

is not equivalent because the && operation is shortcut, so the remaining functions will not be called if any returns false.

When running in the interpreter, you can expect that the first version of your code will actually call all the methods.

Now, the interesting part: after the code is compiled, the compiler is now able to "look into" the various functions determine that they are pure functions, without side effects, and it may compile the two versions identically. In fact, if the functions are very simple, it may be better to compile both versions to always call all three functions, since combining three boolean results and checking it once may be much faster if any of the results are unpredictable.

The compiler may not always be able to determine whether a function has side effects, or there may actually be side effects that only you know don't matter (e.g., an ArrayOutOfBoundsException that you know won't occur but the compiler can't prove). So it's generally better to write the second form, which allows to compiler to use short-circuit evaluation regardless of what it is able to prove about the functions.

BeeOnRope
  • 60,350
  • 16
  • 207
  • 386
  • 1
    If all three methods are free of side effects, the compiler may even reorder them, to do the cheaper check first. Or perform the check that is most likely to return `false` first (to have the highest likelihood of skipping the others). Since this is even true when using the short circuiting variant, it’s still correct to recommend to always use the short circuiting form. – Holger Dec 15 '16 at 12:32
0

Agreed, that the second example will keep evaluating until it reaches a false condition, then it will return "false". The short circuit operator && is being used, therefore once a false condition is encountered, evaluation stops.

Patty P
  • 11
  • 1