0
class Callback{
    public void notify(A arg){ ...}
    public void notify(B arg){ ...}

    private static class B extends A { ...}

    public A create() { return new B(...); }
}

Callback callback = new Callback();

A a = new A(...);
A b = callback.create();

callback.notify(a);
callback.notify(b);

我发现A在这种情况下两次都调用了重载,即使在调试器中它知道a是 type B。这是应该发生的事情还是内部阶级以某种方式搞砸了?

4

2 回答 2

4

在 Java 中,调用的方法签名是在编译时确定的,而不是在运行时确定的。Java 根据静态确定的参数类型确定调用哪个方法,而不是在运行时的实际类型。两者ab都是Atype 的引用,因此两个时间public void notify(A arg)都被调用。有关更多信息,请参阅方法调用表达式

于 2013-04-29T16:58:46.663 回答
1

这应该会发生 - 您正在考虑的是multimethod dispatch,它被其他一些语言支持,但不被 Java 支持。多方法通常要么需要在运行时进行线性时间方法查找,要么需要非常复杂的算法来创建调度表;Java 总是使用声明的类型而不是实际的类型来进行参数匹配,而不是其中任何一种,这实现起来要简单得多,并且不会产生超出动态调度的任何额外运行时成本。

于 2013-04-29T16:58:59.047 回答