t*()
always returns true for this example, where as f*()
always returns false.
Let's say we have the following expression
if ( f1() || t1() || f2() || t2() ){
// do stuff
}
If this is the case the JVM optimizes the execution and only executes f1()
and t1()
because it 'understands' that no matter what f2()
and t2()
yield, the requirement for entering the if-statement is fulfilled and therefor no further calculations are required.
I'm working on a code where I wrote something like this:
boolean b = false;
b |= f1(); // A
b |= t1(); // B
b |= f2(); // C
b |= t2(); // D
One of my colleagues saw this and mentioned that he is not sure, but it could be possible that Java optimizes the statements C and D, because b
is always true
from statement B
onward and this could lead to some issues.
I conducted some tests, it seems as if all of them are properly executed (this is the desired behavior), but I'm still wondering why doesn't this get optimized? I figured he might be right and the JVM understands that once b
is true no |=
operation on it will change its value.
Because that would be a violation of the JLS.
The statement
is equivalent to
In the above, the JLS requires that
b | f1()
is evaluated as follows:b
.f1()
and capture the resulting value|
operator to the two values.The JLS does not allow the compiler to skip the call
f1()
ifb
istrue
1.If you want that semantic (short-circuiting), you need to use
b = b || f1();
and so on. (As you noted:b ||= f1()
is a syntax error.)1 - Actually, in a situation where it was not possible to observe (in a single-threaded program) that an
f1()
call had or had not happened, the optimization would in theory be permissible. But you would only to be able to detect the optimization by carefully examining the native code emitted by the JIT compiler. It it could only happen if the call was strictly side-effect free.