Я работаю над проектом инструментария байт-кода. В настоящее время при обработке объектов, верификатор бросает ошибку большую часть времени. Таким образом, я хотел бы получить вещи четкие касающиеся правила с объектами (я считал JVMS, но не мог найти ответ, который я искал):
Я оснащаю НОВУЮ инструкцию:
исходный байт-код
NEW <MyClass>
DUP
INVOKESPECIAL <MyClass.<init>>
после инструментария
NEW <MyClass>
DUP
INVOKESTATIC <Profiler.handleNEW>
DUP
INVOKESPECIAL <MyClass.<init>>
Обратите внимание, что я добавил вызов к Profiler.handleNEW (), который берет в качестве аргумента ссылку на объект (недавно созданный объект).
Часть кода выше бросает VerificationError. В то время как, если я не добавляю INVOKESTATIC (оставляющий только DUP), он не делает. Таким образом, каково правило, что я нарушаю? Я могу копировать неинициализированную ссылку, но я не могу передать ее как параметр? Я ценил бы любую справку.Спасибо
Верификатор JVM обрабатывает объект, конструктор которого еще не был вызван, как если бы он имел специальный тип времени компиляции, называемый «неинициализированный».
Итак, с точки зрения верификатора, вы передаете объект неправильного типа в качестве первого параметра Profiler.handleNEW ()
, потому что «неинициализированный» не считается подклассом Object (так сказать).
Соответствующая часть спецификации JVM относительно того, как определяется «неинициализированный», находится здесь .
До тех пор, пока не будет вызван конструктор java.lang.Object
(технически он, вероятно, обычно завершается), тип ссылки будет " неинициализированный ". Таким образом, вы не можете многое сделать со ссылкой, прежде чем вызвать для нее конструктор. Это верно и для конструкторов рассматриваемого объекта.