I did some reading up on JLS 15.7.4 and 15.12.4.2, but it doesn't guarantee that there won't be any compiler/runtime optimization that would change the order in which method arguments are evaluated.
Assume the following code:
public static void main (String[] args) {
MyObject obj = new MyObject();
methodRelyingOnEvalOrder(obj, obj.myMethod());
}
public static Object methodRelyingOnEvalOrder(MyObject obj, Object input) {
if (obj.myBoolean())
return null;
else
return input;
}
Is it guaranteed that the compiler or runtime will not do a false optimization such as the following? This optimization may appear correct, but it is wrong when the order of evaluation matters.
In the case where calling obj.myMethod
alters the value that will be returned by obj.myBoolean
, it is crucial that obj.myMethod
be called first as methodRelyingOnEvalOrder
requires this alteration to happen first.
//*******************************
//Unwanted optimization possible:
//*******************************
public static void main (String[] args) {
MyObject obj = new MyObject();
methodRelyingOnEvalOrder(obj);
}
public static Object methodRelyingOnEvalOrder(MyObject obj) {
if (obj.myBoolean())
return null;
else
return obj.myMethod();
}
//*******************************
If possible, please show some sources or Java documentation that supports your answer.
Note: Please do not ask to rewrite the code. This is a specific case where I am questioning the evaluation order guarantee and the compiler/runtime optimization guarantee. The execution of obj.myMethod
must happen in the main
method.
javac
does almost no optimisations at all, it is all done by the JIT. While it may re-order or even eliminate the method call, the end behaviour should be the same. – Unfavorable