在Java中使用重载方法键入顺序

时间:2009-07-02 16:07:40

标签: java types

在Java中给出同一个类的两个方法:

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

,其中

Employee extends Person

如果我打电话:

doSomething( employee )

我发现doSomething( Person )被调用了。

我原本期望调用最接近匹配合约的重载,而不是最抽象的(这是我发现的)

有人可以解释原因吗?

4 个答案:

答案 0 :(得分:13)

使用了最具体的适用重载 - 但是根据employee变量的编译时类型, compile -time确定了该重载。

换句话说:

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

但:

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

请注意,这与覆盖不同,它是目标对象的执行时间类型,这很重要。

答案 1 :(得分:3)

employee是如何宣布的?如果它被声明为Person employee = new Employee();,那么doSomething(Person)确实是最接近的匹配重载。

与覆盖不同,重载是在编译时确定的。因此,即使employee的运行时类型为Employee,也已选择执行Person重载。

请参阅JLS §8.4.9 Overloading

  

当调用方法(§15.12)时,在编译时使用实际参数的数量(以及任何显式类型参数)和参数的编译时类型来确定方法的签名。将被调用(§15.12.2)。如果要调用的方法是实例方法,则将在运行时使用动态方法查找(§15.12.4)确定要调用的实际方法。

答案 2 :(得分:0)

在调用重载时,将调用具有最接近匹配签名的方法。我怀疑您的employeePerson变量。因此,在方法调用中,引用类型employee会导致doSomething(Person person)被选中。

答案 3 :(得分:0)

方法选择在编译时而不是运行时完成,所以如果你有

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

这将调用doSomething(Person),因为声明的类型是Person,而不管实例是否也是Employee。