gpt4 book ai didi

java - 运行时多态性决定

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:48:17 25 4
gpt4 key购买 nike

我在某处读到,运行时多态性是语言中动态类型化的结果。通过检查下面的代码,我们可以看到一个清晰的运行时多态性示例。

class A{
do(){}
}
class B extends A{
do(){}
}
...
A ex = new B();
ex.do();

由于存在父类(super class)类型引用,编译器无法决定实际引用哪个类型并在运行时绑定(bind)方法。但是下面使用相同类定义的用法呢?

我的第一个问题是关于下面的例子;

class A{
do(){}
}
class B extends A{
//no overriding
}
...
A ex = new B();
ex.do();

层次结构中只有一个版本的方法 do()。系统是否仍然等待运行时绑定(bind)方法?还是在编译时绑定(bind)?

我的第二个问题是关于下面的例子;

class A{
do(){}
}
class B extends A{
do(){}
}
...
B ex = new B();
ex.do();

现在有子类(继承链中最低的)类型引用。会在运行时绑定(bind)吗?

最佳答案

当编译非静态方法的调用时,javac 将始终使用 invokevirtual 指令,因此在编译时不会进行任何优化。

但由于方法调用的去虚拟化是一项重要的优化(保存 vtable 查找,可能内联方法),运行时(热点等)将尝试如果可能由于代码分析而应用它.

因此在您的第二个示例(第三个代码块)中,运行时可能认识到它可以将对 A.do 的虚拟调用替换为对 B 的调用.do 因为 ex 实际上是一个 B(在这种情况下运行时应该很容易弄清楚)。

对于您的第一个示例(第二个代码块),还有另一种优化技术。运行时首先看到类 AA.do 的任何调用现在都被编译为静态调用,就好像不存在覆盖 A.do 的派生类一样。如果稍后加载这样的类,运行时将回滚这种乐观的假设并改为引入虚拟方法调用。

关于java - 运行时多态性决定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33499726/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com