javalate-bindingearly-binding

Can the Java compiler do early binding for non-static methods?


Let's say that I have the following class:

public class MyClass {
    public void doSomething() {
        System.out.println("doing something.");
    }
}

Let's further assume, that all my project does is to call that .something() method. No overriding or any other funny-business going on.

MyClass myObj = new MyClass();
myObj.doSomething();

Does the javac compiler notice that this method call is not being overridden, and optimize the binding to "early binding"? I am asking out of curiosity; in any real-world application I would of course sprinkle final, static, and private all over my code.


Solution

  • A bytecode compiler (like javac) typically doesn't do early binding for instance method calls:

    1. The Java model of separate compilation of classes means that this kind of optimization can only be applied when a class is calling one of its of methods. (If javac hypothetically did early binding across classes, changing and recompiling one class could lead to the binding being incorrect.)

    2. There is not a great deal of value, since the JIT compiler (or AOT compiler generator) is where most optimization is performed.

    The JIT compiler in a modern JVM does extensive optimization based on the complete set of classes that have been loaded (so far). This includes optimizing away method dispatching and inlining methods calls. Furthermore, the JIT compiler is smart enough to keep track of key optimizations, and recompile when something like dynamic loading of a new class invalidates the previous optimizations.