Java - 方法在 运行 时间绑定

Java - methods bind at run time

public class Any {

    public static void main(String[] args) {
        A ab = new **B**();
        System.out.println(ab.calc(2.0, 3.1));
    }
}

class A {
    public int calc(int a, int b) {
        return a+b;
    }
}

class B extends A {
    public double calc(double a, double b) {
        return a+b;
    }
}

谁能帮我理解为什么第 4 行会出错: “类型 A 中的方法 calc(int, int) 不适用于参数 (double, double)”

我了解方法在运行时绑定;执行哪个方法取决于调用它的对象的类型。 class B 中的方法计算调用。为什么编译器在 class A.

中寻找方法

非常感谢。

编译器正在查找 class A 因为 ab 的类型是

您需要了解 compile-time 多态性和运行时多态性之间的区别。

方法重载是编译时多态性,编译器总是检查引用。由于 ab 是引用(类型)A,编译器将检查 class A 中的匹配方法。在这种情况下,它不会找到以 double 作为参数的匹配方法。因此它会引发错误。

当您突然按名称加载 A 的子class 时,您可以在 Java 中拥有 运行 时间多态性.因为这可能发生,HotSpot 可能不会选择内联代码或执行其他在 class 动态加载时必须取消的积极优化。信不信由你,HotSpot 仍然可以像这样优化和内联热点方法。当动态加载 subclass 时,它会猛踩刹车并取消优化!它甚至可能 re-inline 代码稍后。相当的把戏。如果你想让你的代码 运行 更快,给 HotSpot 更多的机会来优化,尽可能保持成员的私有性和最终性。无论如何,这对您的设计都有好处。例如,使 class B 最终化是一种承诺,即没有 class 可以进一步专门化 calc 方法。然后,如果你正在使用 B,hotspot 可以内联该方法的代码,如果它在一个循环中,并且可以确保这是安全和高效的。