对字节码和对象的澄清

H-H*_*H-H 7 java verification jvm bytecode object

我正在写一个Bytecode指导员.现在,我试图找出在物体存在的情况下如何做到这一点.我想对我在JVMS中阅读的两行(第4.9.4节)做一些澄清:

1)"验证者在初始化之前拒绝使用新对象的代码."

我的问题是,"使用"在这里意味着什么?我猜它的意思是:把它当作一个方法属性,调用GETFIELDPUTFIELD它,或调用它的任何实例方法.他们的其他禁止用途是什么?而且我相信它遵循其他指令,例如DUP,LOAD并且STORE被允许.

2)"在该方法调用myClass的另一个实例初始化方法或其直接超类之前,该方法可以对此执行的唯一操作是分配在myClass中声明的字段."

这意味着在一个<init>方法中,GETFIELD和PUTFIELD在<init>被调用之前是允许的.但是,在Java中,在调用之前对实例字段执行任何操作super()this()导致编译错误.有人可以澄清一下吗?

3)我还有一个问题.对象引用何时初始化,因此可以自由使用?通过阅读JVMS,我想出了一个对象是否被初始化的答案,取决于每个方法.在某个时间点,可以为方法初始化对象,但不能为另一个方法初始化对象.具体来说,当<init>该方法返回时,对象的方法被初始化.

例如,考虑该main()方法创建了一个对象并调用<init>它然后调用超类<init>.从返回后super(),该对象现在被视为初始化<init>,但尚未初始化main().这是否意味着,在<init>之后super(),我可以将对象作为参数传递给方法,甚至在返回main()之前.

有人可以证实这整个分析是真的吗?感谢您的时间.

ps:我实际上已经向Sun论坛发布了同样的问题但是回复了.我希望我能在这里有更多的运气.谢谢.

更新

首先感谢您的回答和时间.虽然我没有得到一个明确的答案(我有很多问题,其中一些有点模糊),但你的答案和例子,以及随后的实验,对于我更深入地了解JVM如何工作非常有用.

我发现的主要问题是Verifier的行为因不同的实现和版本而不同(这使得字节码操作的工作变得更加复杂).问题在于不符合JVMS,或者验证者的开发人员缺乏文档,或者JVMS在验证者的区域中有一些微妙的模糊性.

最后一件事,SO Rocks !!! 我在官方的Sun JVM规范论坛上发布了同样的问题,直到现在我仍然没有回答.

Ste*_*n C 1

我建议您下载 OpenJDK 源代码的副本,并查看验证程序实际检查的内容。如果不出意外,这可能会帮助您理解 JMV 规范的含义。

(但是,@Joachim 是对的。依赖验证器实现的作用而不是规范所说的内容是相当危险的。)