字节码和对象

7

我正在进行字节码注入项目。目前在处理对象时,验证器大多数情况下会抛出错误。因此,我希望明确有关对象规则的事项(我阅读了JVMS,但没有找到我要寻找的答案):

我正在对NEW指令进行注入:

原始字节码

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

仪器化之后

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

请注意,我添加了一个调用 Profiler.handleNEW() 的方法,并将新创建的对象作为参数传递。

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


在对象的构造函数完成之前,绝对不应该将任何对象实例作为参数传递,无论验证器是否允许。 - Yishai
即使我不操作对象,只是存储它的引用? - H-H
2
@HH 是的,请看这里:http://www.ibm.com/developerworks/forums/thread.jspa?messageID=13894854 - Yishai
2个回答

4
JVM验证器将一个尚未调用构造函数的对象视为具有特殊的编译时类型"未初始化"。因此,从验证器的角度来看,您将错误类型的对象作为第一个参数传递给Profiler.handleNEW(),因为"未初始化"不被认为是Object的子类(可以这么说)。关于如何定义"未初始化"的JVM规范相关部分,请参见此处

1

在调用java.lang.Object构造函数之前(技术上它可能已经正常退出),引用的类型是“未初始化”的。因此,在对其调用构造函数之前,您无法对引用执行太多操作。这也适用于所讨论对象的构造函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接