|
|
1
4
一切都是为了表现。当通过计算编译时类型(aka:static type)时,jvm可以计算运行时类型(aka:dynamic type)的虚拟函数表中被调用方法的索引。使用这个索引步骤3只需访问一个可以在恒定时间内完成的数组。不需要循环。 例子:
默认情况下,
现在,考虑这个调用:
通过计算x的静态类型
之后,每当jvm处理
注意,不管x的动态类型是什么,方法的索引都保持不变,即:即使x指向b的实例,第6个方法仍然是
更新 [根据你的最新情况]:你是对的。为了执行虚拟方法分派,jvm需要的是方法的名称+签名(或vtable中的偏移量)。但是,jvm不会盲目地执行任务。它首先在一个名为 verification (也见) here ) 验证表达了jvm的设计原则之一: 它不依赖编译器生成正确的代码 . 它在允许执行代码之前检查代码本身。特别是,验证器检查每个调用的虚拟方法是否实际由接收方对象的静态类型定义。显然,执行这种检查需要接收器的静态类型。 |
|
|
2
1
在阅读了文档之后,我并不是这样理解的。我认为您已经将步骤2和步骤3进行了转换,这将使整个系列事件更符合逻辑。 |
|
|
3
1
据推测,编译器已经发生了1和2。我怀疑,至少部分目的是确保它们在运行时环境中仍然与类的版本保持一致,这可能与代码编译时所针对的版本不同。
我还没消化
|
|
|
4
1
我猜答案是“B”。
#1由描述 5.4.3.3 Method Resolution ,这是一些重要的检查。例如,1检查编译时类型中方法的可访问性,如果不是,则可能返回illegalaccesserror:
如果只检查运行时类型(通过3),则运行时类型可能会非法扩展重写方法的可访问性(也称为“坏事”)。编译器确实应该防止这种情况,但jvm仍然在保护自己不受恶意代码(例如,手动构造的恶意代码)的攻击。 |
|
|
5
0
要完全理解这些东西,您需要了解方法解析在Java中是如何工作的。如果你正在寻找一个深入的解释,我建议看这本书,“在Java虚拟机内部”。第8章“链接模型”的以下章节可在线查阅,似乎特别相关: (constant_methodref_info entries是类文件头中描述该类调用的方法的项。) 感谢ITAY鼓励我用谷歌搜索找到这个。 |