7

我正在做一个字节码检测项目。目前在处理对象时,验证器大部分时间都会抛出错误。所以我想弄清楚关于对象规则的事情(我阅读了 JVMS 但找不到我正在寻找的答案):

我正在检测新指令:

原始字节码

NEW <MyClass>
DUP
INVOKESPECIAL <MyClass.<init>>

仪器后

NEW <MyClass>
DUP
INVOKESTATIC <Profiler.handleNEW>
DUP
INVOKESPECIAL <MyClass.<init>>

请注意,我添加了对 Profiler.handleNEW() 的调用,该调用将对象引用(新创建的对象)作为参数。

上面的代码会引发 VerificationError。如果我不添加 INVOKESTATIC(只留下 DUP),它不会。那么我违反的规则是什么?我可以复制一个未初始化的引用,但我不能将它作为参数传递?我将不胜感激任何帮助。谢谢

4

2 回答 2

4

JVM 验证程序将尚未调用其构造函数的对象视为具有称为“未初始化”的特殊编译时类型。

因此,从验证者的角度来看,您将错误类型的对象作为第一个参数传递给Profiler.handleNEW(),因为“未初始化”不被视为 Object 的子类(可以这么说)。

JVM 规范中关于如何定义“未初始化”的相关部分在这里

于 2010-05-07T19:41:42.773 回答
1

java.lang.Object调用构造函数之前(从技术上讲,它可能正常退出),引用的类型是“未初始化的”。因此,在调用构造函数之前,您不能对引用做太多事情。在相关对象的构造函数中也是如此。

于 2010-05-07T19:28:09.727 回答