As summarised in my title, I was wondering whether expressions involving constants defined at instantiation get simplified during compile-time?
For example, I have a heap class where I have a final boolean isMinHeap whose value is set in the heap's constructor. The heap's methods then use this boolean in certain places. Can the compiler optimise this to simplify all these expressions that involve this boolean, or are the expressions computed in full every time a method is called?
Thanks!
EDIT: Because someone asked me for a more concrete example, here is a method that is called every time a node is removed from the heap (to assist with re-heapifying the tree):
private boolean requiresRepositioningDown(BTNode<T> node)
{
boolean childIsSmaller = (node.getLeft().getValue().compareTo(
node.getValue()) < 0)
|| (node.getRight() != null && node.getRight().getValue().compareTo(
node.getValue()) < 0);
if (isMinHeap && childIsSmaller || !isMinHeap && !childIsSmaller)
return true;
else
return false;
}
The expression with isMinHeap here would seem to get evaluated in full every time, whereas if the heap was made a max-heap at instantiation, the whole right-side of the expression could (and should) just be ignored.
It very likely won't. First of all, it's still not constant for the class at compile time; there can be still two instances where it differs. And that sort of optimisation is usually left to the JIT compiler.
Even if your constant is never set to anything else this will not be optimised. E.g.
public class Heap {
final boolean isMinHeap;
public Heap() {
isMinHeap = true;
}
@Override
public String toString() {
if (isMinHeap) return "Min!";
return "Not Min";
}
}
compiles to
public java.lang.String toString();
Code:
0: aload_0
1: getfield #2 // Field isMinHeap:Z
4: ifeq 10
7: ldc #3 // String Min!
9: areturn
10: ldc #4 // String Not Min
12: areturn
Note that the conditional is still there. The JIT compiler might opt to remove it completely if the method is used often since it should know that the final
member cannot change. But that's a bit hard to observe.
If you immediately set isMinHeap
to a value, though, and not do it in a constructor, then the optimisation is performed:
public class Heap {
final boolean isMinHeap = true;
public Heap() {
}
@Override
public String toString() {
if (isMinHeap) return "Min!";
return "Not Min";
}
}
compiles toString
to:
public java.lang.String toString();
Code:
0: ldc #3 // String Min!
2: areturn