Does Java have lazy evaluation?
Solution 1:
Well, as far as the language is concerned - yes, both functions are called.
If you rewrote the function to this:
public boolean isTrue() {
return isBTrue() || isATrue();
}
then the second function will not be called, if the first is true.
But this is short-circuit evaluation, not lazy evaluation. Lazy evaluation case would look something like this:
public interface LazyBoolean {
boolean eval();
}
class CostlyComparison implements LazyBoolean {
private int a, b;
public CostlyComparison(int a, int b) {
this.a=a;
this.b=b;
}
@Override
public boolean eval() {
//lots of probably not-always-necessary computation here
return a > b;
}
}
public LazyBoolean isATrue() {
return new CostlyComparison(10,30); //just an example
}
public boolean isTrue() { // so now we only pay for creation of 2 objects
LazyBoolean a = isATrue(); // but the computation is not performed;
LazyBoolean b = isBTrue(); // instead, it's encapsulated in a LazyBoolean
return b.eval() || a.eval(); // and will be evaluated on demand;
// this is the definition of lazy eval.
}
Solution 2:
In Java (and other C-like languages), this is referred to as short-circuit evaluation.*
And yes, in the second example isATrue
is always called. That is, unless the compiler/JVM can determine that it has no observable side-effects, in which case it may choose to optimize, but in which case you wouldn't notice the difference anyway.
*
I originally suggested that this was quite distinct from lazy evaluation, but as @Ingo points out in comments below, that's a dubious assertion. One may view the short-circuit operators in Java as a very limited application of lazy evaluation.
However, when functional languages mandate lazy-evaluation semantics, it's usually for a quite different reason, namely prevention of infinite (or at least, excessive) recursion.