栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

当在子类上调用其父类中声明的静态方法时,为什么不调用子类的静态初始化器?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

当在子类上调用其父类中声明的静态方法时,为什么不调用子类的静态初始化器?

我认为这与jvm规范的这一部分有关:

每个框架(第2.6节)都包含对当前方法类型的运行时常量池(第2.5.5节)的引用,以支持方法代码的动态链接。方法的类文件代码是指要调用的方法和要通过符号引用访问的变量。动态链接将这些符号方法引用转换为具体的方法引用,根据需要加载类以解析尚未定义的符号,并将变量访问转换为与这些变量的运行时位置关联的存储结构中的适当偏移量。

方法和变量的这种较晚的绑定使方法使用的其他类中的更改不太可能破坏此代码。

在jvm规范的第5章中,他们还提到:由于以下原因,可能会初始化类或接口C:

执行引用C的Java虚拟机指令new,getstatic,putstatic或invokestatic的任何一条(§new,§getstatic,§putstatic,§invokestatic)。这些指令通过字段引用或方法引用
直接或间接 引用类或接口。

在执行getstatic,putstatic或invokestatic指令后,如果尚未 解析已声明字段或方法的类或接口, 则将对其进行初始化。

在我看来,文档的第一部分似乎指出,任何符号引用都可以简单地解析和调用,而不考虑其来源。关于方法解析的该文档对此有以下说法:

[M] ethod解析尝试在C及其超类中定位引用的方法:

如果C完全使用方法引用指定的名称声明了一个方法,并且声明是签名多态方法(第2.9节),则方法查找成功。描述符中提到的所有类名都将被解析(第5.4.3.1节)。

解析的方法是签名多态方法声明。C不必使用方法参考指定的描述符来声明方法。

否则,如果C使用方法参考指定的名称和描述符声明方法,则方法查找成功。

否则,如果C具有超类,则对C的直接超类递归调用方法解析的步骤2。

因此,从子类调用它的事实似乎被忽略了。为什么要这样呢?在您提供的文档中,他们说:

目的是类或接口类型具有一组初始化器,这些初始化器将其置于一致状态,并且该状态是其他类观察到的第一个状态。

在您的示例中,当Sub静态初始化时,您更改了Super的状态。如果在调用Sub.staticMethod时发生初始化,则jvm认为相同方法的行为会有所不同。这可能是他们在谈论要避免的不一致之处。

另外,这是一些执行staticMethod的反编译类文件代码,显示了invokestatic的使用:

Constant pool:    ...    #2 = Methodref          #18.#19        // Sub.staticMethod:()V...Code:  stack=0, locals=1, args_size=1     0: invokestatic  #2       // Method Sub.staticMethod:()V     3: return


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/431423.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号