Java 实例方法的堆栈帧中的超级引用在哪里?
Where is the super reference in a Java instance method's stack frame?
我阅读了 Bill Venner 的优秀 Java 虚拟机内部一书,该书在第 5 章中详细探讨了 JVM 堆栈框架的组成等内容。
(本书的这一章也恰好在这里正式发布:https://www.artima.com/insidejvm/ed2/jvm8.html)
除了这本书之外,我对一些 JVM 的运行时数据区域进行了比较多的研究,尤其是它们的栈和堆。
在实例方法的堆栈框架中,局部变量部分构成了一个包含方法参数(或参数)的单词数组,局部变量 和“隐藏”这个引用.
我想知道的是,超级引用存储在哪里,因为它在任何非静态上下文中也始终可用(即实例方法体或初始化程序块),对象 class 除外。它是否存储在引用“this”旁边的某个地方?如果是,那么为什么它似乎总是从堆栈框架中遗漏 representations/overviews?
没有“超级”参考。
当你这样做时:
super.foo()
您“似乎”在一个名为“super”的对象上调用 foo
,但这仅仅是 Java 的语法,并不一定反映幕后发生的事情。转换此调用时,它会转换为 invokespecial
指令,调用超类的 foo
方法。
将此与 this.foo()
调用进行比较,后者转换为 invokevirtual
指令。与 invokespecial
不同,这将进行动态调度,根据 this
.
的运行时类型选择正确的方法来调用
请注意,在这两种情况下,在调用方法之前都有一个 aload_0
指令,将 this
引用加载到堆栈上。
'hidden this' 引用并不像您想象的那样存在。
如果调用super.toString()
,则super
被解析并存储到'hidden this'。
因此,一旦创建了 runInstanceMethod()
的堆栈帧(在我们的示例中 toString()
),'hidden this' IS 前一个 super.
也就是说,'hidden this'总是引用当前成员方法所属的对象。
我阅读了 Bill Venner 的优秀 Java 虚拟机内部一书,该书在第 5 章中详细探讨了 JVM 堆栈框架的组成等内容。 (本书的这一章也恰好在这里正式发布:https://www.artima.com/insidejvm/ed2/jvm8.html) 除了这本书之外,我对一些 JVM 的运行时数据区域进行了比较多的研究,尤其是它们的栈和堆。
在实例方法的堆栈框架中,局部变量部分构成了一个包含方法参数(或参数)的单词数组,局部变量 和“隐藏”这个引用.
我想知道的是,超级引用存储在哪里,因为它在任何非静态上下文中也始终可用(即实例方法体或初始化程序块),对象 class 除外。它是否存储在引用“this”旁边的某个地方?如果是,那么为什么它似乎总是从堆栈框架中遗漏 representations/overviews?
没有“超级”参考。
当你这样做时:
super.foo()
您“似乎”在一个名为“super”的对象上调用 foo
,但这仅仅是 Java 的语法,并不一定反映幕后发生的事情。转换此调用时,它会转换为 invokespecial
指令,调用超类的 foo
方法。
将此与 this.foo()
调用进行比较,后者转换为 invokevirtual
指令。与 invokespecial
不同,这将进行动态调度,根据 this
.
请注意,在这两种情况下,在调用方法之前都有一个 aload_0
指令,将 this
引用加载到堆栈上。
'hidden this' 引用并不像您想象的那样存在。
如果调用super.toString()
,则super
被解析并存储到'hidden this'。
因此,一旦创建了 runInstanceMethod()
的堆栈帧(在我们的示例中 toString()
),'hidden this' IS 前一个 super.
也就是说,'hidden this'总是引用当前成员方法所属的对象。