Java中的静态绑定和动态绑定

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中的静态绑定和动态绑定相关的知识,希望对你有一定的参考价值。

起初我是初学者 我已经看过很多教程,阅读了很多例子,甚至试图从JLS中理解这个主题,但我仍然有一些困惑或误解。

让我告诉你我无法理解的问题。

想象一下,我们有三个类ParentChild1Child2如下:

class Parent {
    void doSmth(Object o) {
        System.out.println("Parent.doSmth");
    }
}

class Child1 extends Parent {
    void doSmth(Object o) {
        System.out.println("Child1.doSmth");
    }
}

class Child2 extends Parent {
    void doSmth(String s) {
        System.out.println("Child2.doSmth");
    }
}

class Test {
    public static void main(String[] args) {
        Parent p1 = new Child1();
        Parent p2 = new Child2();

        p1.doSmth("String");
        p2.doSmth("String");
    }
}

我理解的是,因为p1p2的引用来自Parent类型,所以doSmth(Object)只对编译器可见。

对于p1.doSmth("String");,编译器没有绑定它,因为有一个重写方法,所以它只是让它让JVM在运行时绑定它(动态绑定)。

而对于p2.doSmth("String");,编译器绑定它,因为它没有找到它的重写方法(静态绑定)。

问题是,我所说的是真的吗?或者我有误解?如果它是假的,那么请告诉我在这种情况下编译器采取了哪些步骤? 如果这是真的,那么编译器如何期望p1.doSmth它有一个重写方法(虽然它不知道它的真实类型),而在p2.doSmth它只是绑定它?我错过了什么?

对不起,这真让我头疼

答案

试着总结一下讨论。根据需要编辑。

Java中的静态绑定在编译时发生,而动态绑定在运行时发生。

在编译时,p1和p2都是Parent的类型,Parent有doSmth(Object)方法,因此两行都绑定到同一个方法。

    p1.doSmth("String");
    p2.doSmth("String");

在运行时,动态绑定进入画面。

p1是Child1的实例,Child1重写了doSmth(Object),因此使用了Child1的实现。

p2是Child2的实例,Child2不覆盖doSmth(Object),因此调用Parent的继承方法的实现。

以上是关于Java中的静态绑定和动态绑定的主要内容,如果未能解决你的问题,请参考以下文章

Java 动态绑定 静态绑定

Java方法的静态绑定与动态绑定讲解(向上转型的运行机制详解)

Scala核心编程_第08章 面向对象编程(中级补充)--java动态绑定与静态绑定

Scala核心编程_第08章 面向对象编程(中级补充)--java动态绑定与静态绑定

Java : 多态表现:静态绑定与动态绑定(向上转型的运行机制)

从编译器角度理解虚函数静态绑定和动态绑定