javamethodsjvmrepeat

Successive use of same method in block recalculates the method?


I've always assumed every time I call a method in Java the method is executed again. I've assumed the return value is not stored automatically unless I store it in a variable.

Then I ran across this code in Princeton's algs4.BST class where they call three methods twice each:

private boolean check() {
    if (!isBST())            StdOut.println("Not in symmetric order");
    if (!isSizeConsistent()) StdOut.println("Subtree counts not consistent");
    if (!isRankConsistent()) StdOut.println("Ranks not consistent");
    return isBST() && isSizeConsistent() && isRankConsistent();
}

Are they simply not concerned with performance? Or is the compiler smart enough keep the first return value of each method to use in the return statement?

Sorry if this is a duplicate seems like this answer should exist but I can't find it here or in Java docs. I found these (and others) but they don't answer my question:

Is this the cleanest way to repeat method call in Java?

How to call a method without repeat from other methods in java


Solution

  • The Java Language Specification explicitly and unconditionally states that evaluation of a method invocation expression involves executing the designated method's code. JLS 8 puts it this way:

    At run time, method invocation requires five steps. First, a target reference may be computed. Second, the argument expressions are evaluated. Third, the accessibility of the method to be invoked is checked. Fourth, the actual code for the method to be executed is located. Fifth, a new activation frame is created, synchronization is performed if necessary, and control is transferred to the method code.

    (JLS 8, 15.12.4; emphasis added)

    Thus, invoking a method a second time incurs its cost a second time, regardless of whether the same value can be expected to be computed. It is conceivable that JIT compilation could optimize that, but there are more considerations there than whether the same result is going to be computed, and you're anyway unlikely to see any JIT action triggered by just two invocations of a given method.

    Bottom line: yes, the author of the code was simply not concerned with performance. They may have considered the implementation presented to be clearer than one that avoided redundant method invocations, or they may have had some other personal reason for the choice. This kind of disregard for practicalities is not uncommon in code serving academic purposes, such as that presented.