Wesson Wang
Wesson Wang

Reputation: 13

Why Method Overload Resolution have to be done at compile time in JAVA?

Here a simple code block:

public class CYoungMan extends YoungMan{
    @Override
    public String meet(Object obj) {
        return obj.getClass().getSimpleName();
    }
    @Override
    public String meet(String str) {
        return "String class";
    }
    public static void main(String[] args) throws Throwable {
        Object str = "katie";
        YoungMan ym = new CYoungMan();
        ym.meet(str);
    }
}

For a method call ym.meet(str), as we know,

  1. compiler determines a symbolic reference combined by the class YoungMan and the method String meet(Object obj);
  2. then in the runtime, JVM locate the method block by runtime type of ym and its inheritance hierarchy.

My question is, why not take (1) to be implemented in runtime and we locate the overload method by runtime type of parameters?

What I more concern is, why Java designers decided to do that (as I described in (1) and (2) ) and why not chose Multiple dispatch in runtime instead (like My suggestion) ? Is there any official explanation?

Upvotes: 0

Views: 587

Answers (2)

flakes
flakes

Reputation: 23644

Although overloaded methods share the same name in code, a method with n overloads will have n different method signatures. These methods can accept and return differing parameters and return values. The compiler needs to know which method signature to use in order to understand if the code its compiling is valid.

Consider the following overloaded method:

class Translator {
    String translate(int i) { return String.valueOf(i); }
    int translate(String s) { return Integer.valueOf(s); }
}

These methods share the same name, but have very different signatures. If you were to select one vs the other then you may end up with an invalid executable.

Overriden methods on the other hand share the same signature. Because they have the same input types and return types, it is possible to choose the implementation at runtime while still ensuring compile time safety.

Choosing an overloaded method does not cause any degradation to performance. After compile time, the cost to call one overloaded method vs another is the same as calling methods with separate names altogether. Invoking a virtual method is already expensive, and adding parameter resolution to the process would only slow down execution further.

Upvotes: 2

The short version is because that's how the Java system decided to do it (among other things, it's a lot faster at runtime). Groovy (among other JVM languages) can do dynamic dispatch, and invokedynamic was added to the JVM instruction set in Java 7 to help make this sort of approach more efficient.

Upvotes: 2

Related Questions