java - 以下代码是否将后期绑定应用于静态方法?多态 Java
问题描述
所以我在玩 Java 来理解多态的概念,我写了这个:
public class Practice
{
public static void main(String[] args)
{
Parent p = new Child();
p.instanceMethod();
}
}
class Child extends Parent {
public void instanceMethod(){
System.out.println("child's instance method");
staticMethod();
}
public static void staticMethod() {
System.out.println("child's static method");
}
}
class Parent {
public void instanceMethod(){
System.out.println("parent's instance method");
staticMethod();
}
public static void staticMethod() {
System.out.println("parent's static method");
}
}
所以这个的输出是:
child's instance method
child's static method
为什么从子类调用静态方法而不是从它的静态类型,父类?
是不是因为它首先被子类中的实例方法调用,所以此时它的类型已经是完全动态的,也就是子类的类型?
解决方案
静态方法不会“做”多态性。完全没有。
非静态(即实例)方法可以。方法的签名完全是静态绑定的;查找在类型层次结构中实际运行的方法的实际前景完全是动态完成的(后期绑定)。
对于静态方法,整个事情完全是静态的。
那么,让我们来看看这段代码:
p.instanceMethod()
表达式p
的类型是Parent
。编译器查看可用的签名Parent
及其所有超类型,并确定此调用instanceMethod()
尝试调用的完整方法签名是void instanceMethod()
. 此调用(Parent
:: instanceMethod()V
in bytecode speak)被编码在发出的 .class 文件中。
在运行时,系统检查表达式解析为的实际运行时类型p
(这是new Child()
您之前所做的),并进行动态调度。的public void instanceMethod()
ofChild
明显覆盖了 from 的一个Parent
,因此被选中并执行,因此"child's instance method"
被打印。
staticMethod()
在儿童
接下来,让我们看一下 staticMethod 调用:在编译时,javac 确定 this 显然是staticMethod()
对那里的引用,在Child
. 它在字节码中将字节码编码INVOKESTATIC
为Child
:: staticMethod()V
。动态分派现在或从未应用于静态方法调用。
在运行时..调用该方法。
就那么简单。
也许您期望静态方法仍然首先检查调用上下文,但这不是 java 的工作方式。
推荐阅读
- angular - Angular 7 将表单数据映射到 API 模型
- java - javax.net.ssl.SSLHandshakeException?
- sql - 无法在 SQL Server Express 2017 中创建表
- mongodb - 每个动作类型的复杂时间序列查询时间差
- javascript - Jquery DataTable:子行控制错误
- mysql - 从频繁更新的 mysql 表中检索成块的行数据
- javascript - 如何在假期使用 php 或 Javascript 在 wordpress 中更改 css
- google-cloud-platform - 将消息发布到特定子文件夹
- java - 在 restful 中返回类型 xml 或 json
- wordpress - ACF(高级自定义页面)选项页面更改将作为全局选项在网络中应用