Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Java pick which overloaded function to call?

This is a purely theoretical question.

Given three simple classes:

class Base {
}

class Sub extends Base {
}    

class SubSub extends Sub {
}

And a function meant to operate on these classes:

public static void doSomething(Base b) {
  System.out.println("BASE CALLED");
}
public static void doSomething(Sub b) {
  System.out.println("SUB CALLED");
}

It seems that the followign code:

SubSub ss = new SubSub();
doSomething(ss);

could legitimately result in printing either BASE CALLED, or SUB CALLED, since SubSub can be casted to both of those. In fact, removing the Sub version of the function causes BASE CALLED to be printed. What actually happens is that "SUB CALLED" is printed. This seems to mean that which function is called doesn't depend on the order the functions are defined in, as the Base version was called first.

Does Java just look at all the different versions of the function and pick the one which requires the smallest traversal up the inheritance stack? Is this standardized? Is it written out in any documentation?

like image 895
Claudiu Avatar asked Dec 22 '08 04:12

Claudiu


People also ask

How does Java choose overloaded method?

Method overloading in java is based on the number and type of the parameters passed as an argument to the methods. We can not define more than one method with the same name, Order, and type of the arguments.

How does Java decide the method to call?

Since in java all method binding is late-binding unless the method is static , final or private , and late-binding is done by JVM which precomputes method table for each class and then do a table look up during runtime in normal method call.

Which type determines the overloaded method which will be used at the compile time?

Explanation: 1. Polymorphism, which works at compile-time, includes method overloading.

How are function calls matched with overloaded functions?

The compiler selects which overloaded function to invoke based on the best match among the function declarations in the current scope to the arguments supplied in the function call. If a suitable function is found, that function is called. "Suitable" in this context means either: An exact match was found.


2 Answers

The formal specification can be found in part 15.12.2.5 of the Java Language Specification (JLS). Thanks to generics this is pretty complicated, so you might want to look at same section of the first edition of the JLS.

It basically says that the compiler tries to find a version of the method where all parameters including the object the method is called upon are most specific. If no such method exists (e.g. since you have method(Base, Sub) and method(Sub, Base) but not method(Sub, Sub)), then the compilation fails.

Note that the actual choice of method depends on the dynamic type of the target object for instance methods, but not for the parameters. Your example would still work the same on the instance level.

You should be able to give the compiler a helping hand by casting or redeclaring the type of ss. If the declared type of the variable matches a signature exactly then everything is clear for the compiler and maintenance programmers as well. It doesn't matter if you then assign a more specific type as long as the declared type matches.

like image 150
Peter Becker Avatar answered Oct 03 '22 11:10

Peter Becker


As far as I know, Java and C++ make this decision at compilation time (since these are static functions that are not dynamically dispatchable) based on the most specific matching that they can make. If your static type is SubSub and you have an overload that takes SubSub, this is the one that will be invoked. I'm fairly sure it's in both standards.

If you have a reference or pointer to Base, even if it contains a Sub or a SubSub, you will match the version that takes a Base because at compile time, that is the only assurance that the compiler has.

like image 45
Uri Avatar answered Oct 03 '22 10:10

Uri