tags:

views:

126

answers:

4

Hi

Given two methods on the same class in Java :

public void doSomething( Person person );
public void doSomething( Employee employee );

where

Employee extends Person

If I call :

doSomething( employee )

I find that doSomething( Person ) get's invoked.

I'd have expected the overload with the closest matching contract be invoked, not with the most abstract (which is what I'm finding)

Could someone explain why?

Regards

Marty

+1  A: 

How was employee declared? If it was declared as Person employee = new Employee();, then doSomething(Person) is indeed the closest matching overload.

Unlike overrides, overloads are determined at compile time. Therefore, even though the runtime type of employee is Employee, the Person overload has already been chosen to be executed.

See the JLS §8.4.9 Overloading:

When a method is invoked (§15.12), the number of actual arguments (and any explicit type arguments) and the compile-time types of the arguments are used, at compile time, to determine the signature of the method that will be invoked (§15.12.2). If the method that is to be invoked is an instance method, the actual method to be invoked will be determined at run time, using dynamic method lookup (§15.12.4).

Michael Myers
+6  A: 

The most specific applicable overload is used - but that overload is determined at compile-time, based on the compile time type of the employee variable.

In other words:

Employee employee = new Employee();
doSomething(employee); // Calls doSomething(Employee)

but:

Person employee = new Employee();
doSomething(employee); // Calls doSomething(Person)

Note that this is unlike overriding where it's the execution time type of the target object which is important.

Jon Skeet
Boy your quick Jon, second time you've beet me to the answer today :)
David Waters
No fair, I beat both of you (although I must admit my first version wasn't extremely helpful).
Michael Myers
The way Jon answers is like reading a reference manual--complete, concise, to the point.Man this guy pisses me off. :)
Bill K
A: 

On calling an overloaded, the method with the closest matching signature will be called. I suspect your employee is a Person variable. So at the method call, the reference type of employee causes your doSomething(Person person) to get selected.

aberrant80
A: 

The method selection is done at compile time not run time, so if you had

Person employee = new Employee();
doSomething(employee);

This would call doSomething(Person) as the declared type is Person, regardless of the fact the instance is also a Employee.

David Waters