【问题标题】:How is dynamic binding performed in java? (I have specific details)java中的动态绑定是如何实现的? (我有具体细节)
【发布时间】:2018-01-09 14:44:43
【问题描述】:

我看到了一些与此类似的早期问题,但我正在寻找更具体的答案。

1) 在这种情况下,JVM 如何/何时执行动态绑定?

  • 我尝试使用超类引用变量superobj 调用派生类方法derivedFunc1()。它失败了(我的失败假设:编译器说成员 derivedFunc1() 不属于为超类引用变量分配(或限制)的内存。)

  • 我尝试使用超类引用变量superobj 调用方法superFunc1()。尽管在超类中有superFunc1(),但它“以某种方式”从派生类调用superFunc1()。 (这与我的假设相矛盾,因为访问超出了其受限的内存范围)。

所以我的问题:

1) superobj 如何能够访问派生类成员 superFunc1() 但不能访问另一个派生类成员 derivedFunc1()

2) 谁/什么要求 JVM 执行动态绑定?

编辑:图像可能无效,因为我知道“派生类对象不创建超类对象”

import java.util.*;  
import java.text.*;

public class MyLocale {
    public static void main(String[] args) {
        MySuper superobj=new MyDerived();
        superobj.derivedFunc1(); //Statment1: fails because it cannot call functions from  derived class. (Okay I understand this part) 
        superobj.superFunc1(); //Statment2: has 2 options (one in super, one in derived) to call from and here it calls derived function. 

    }

}

class MySuper {
    void superFunc1() {
        System.out.println("Super");
    }

}
class MyDerived extends MySuper{
    void derivedFunc1() {
        System.out.println("Derived");
    }
    void superFunc1() {
        System.out.println("Derived");
    }
}

【问题讨论】:

  • 你应该阅读这篇文章docs.oracle.com/javase/tutorial/java/IandI/subclasses.html 并修正你的术语,以便清楚你在问什么。试着坚持“方法”,不要在没有明确说明发生了什么的情况下说“它失败了”之类的话,并澄清你希望你的班级拥有的关系。例如,“超类”和“基类”是同义词。

标签: java dynamic-binding


【解决方案1】:

发生了一些事情。

1) MyBaseMySuper 的子类,这意味着MyBasesuperFunc1() 将覆盖MySupersuperFunc1()

2) MySuper superobj=new MyBase(); 采用 MyBase 实例,但告诉编译器将其视为 MySuper

3) MySuper 只有一个方法 (superFunc1),所以这是您可以在 superobj 上调用的唯一方法

4) 但是,在运行时,JVM 会在 superobj 上动态查找 (invokevirtual) superFunc1,这实际上是 MyBase 的一个实例,因此它会调用 MyBase.superFunc1

相关阅读:https://www.javaworld.com/article/2076949/learn-java/how-the-java-virtual-machine-handles-method-invocation-and-return.html

【讨论】:

  • 好的,但是限制 superobj 访问 baseFunc1() 但可以访问 superFunc1
  • @sql_dummy 编译器:编译器将superobj 视为MySuper 的一个实例(因为这就是superobj 的声明方式)。 MySuper 没有baseFunc1,所以编译器会报错。
  • 那么在superFunc1()的情况下,为什么编译器只是解析为超类中的func,而是切换到动态绑定。 (很抱歉我无法理解您提供的文章,我会尝试再看几遍,但同时我接受了 cmets 的帮助。
  • 编译器实际上并不进行函数调用。在编译时它只检查代码是否有效,然后在运行时 jvm 使用invokedynamic 调用来解析superFunc1invokedynamic 将查看其调用的实例 (MyBase)。对于baseFunc1,它甚至没有达到那个点(如果达到了,它会起作用),因为编译器首先会发出一个错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多