Я пишу прибор для байт-кода. Прямо сейчас, я пытаюсь выяснить, как это сделать при наличии объектов. Я хотел бы некоторые разъяснения по двум линиям, которые я прочитал в JVMs (раздел 4.9.4):Уточнения по байт-коду и объектам
1) «Испытатель отвергает код, который использует новый объект, прежде чем он был инициализирован.»
Мой вопрос: что здесь означает «использует»? Я предполагаю, что это означает: передавать его как атрибут метода, вызывая на нем GETFIELD
и PUTFIELD
или вызывающий на нем какой-либо метод экземпляра. Являются ли их другие запретные виды использования? И я считаю, что следует, что допускаются другие инструкции, такие как DUP
, LOAD
и STORE
.
2) «Перед тем, что метод вызывает другой метод инициализации экземпляра MyCLASS или его прямой суперкласс на этого, единственную операцию метод может выполнить на этом назначении поля, объявленное в пределах MyCLASS.»
Это означает, что в <init>
методы ПолучитьПолеЗаголовок и PUTFIELD разрешены перед другим <init>
называется. Однако в Java, выполняющем любую операцию в поле экземпляра перед вызовом super()
или this()
, возникает ошибка компиляции. Может ли кто-нибудь прояснить это?
3) У меня есть еще один вопрос. Когда инициализируется ссылка на объект и, следовательно, готова к свободному использованию? От чтения JVMS я придумал ответ, что независимо от того, инициализирован ли объект или нет, зависит от каждого метода. В определенный момент времени объект может быть инициализирован для метода, но не для другого. В частности, объект инициализируется для метода, когда возвращается <init>
, вызываемый этим методом.
Например, обратите внимание, что метод main()
создал объект и вызвал <init>
, который затем назывался суперклассом <init>
. После возврата из super()
объект теперь считается инициализированным <init>
, но еще не инициализирован для main()
. Означает ли это, что в <init>
после super()
я могу передать объект в качестве параметра методу, даже до возврата из main().
Может ли кто-нибудь подтвердить, что весь этот анализ верен? Спасибо за ваше время.
ps: Я фактически опубликовал тот же вопрос на форумах Sun, но с ответом. Надеюсь, мне повезет больше. Спасибо.
Update
Первое спасибо за ответы и время. Хотя я не получил четкого ответа (у меня было много вопросов, а некоторые из них были немного расплывчаты), ваши ответы и примеры и последующие эксперименты были чрезвычайно полезны для меня, глубже понимая, как работает JVM.
Главное, что я обнаружил, это то, что поведение Verifier отличается различными реализациями и версиями (что значительно затрудняет работу манипуляции с байт-кодом).Проблема заключается либо в несоответствии JVMS, либо в отсутствии документации от разработчиков верификатора, либо у JVMS есть некоторые тонкие неопределенности в области верификатора.
Последнее, SO Rocks !!! Я опубликовал тот же вопрос на официальном форуме Sun JVM Specifications, и до сих пор я до сих пор не получил ответа.
Это не плохая идея, но вы должны быть осторожны с этим , В прошлом фактический верификатор был менее строгим в отношении правил, чем спецификация. Вполне возможно, что такие случаи все еще происходят. –
Да, я обнаружил, что разные реализации Verifier имеют разный уровень строгости. Например, верификатор JustIce Apache BCEL не разрешает STORE на неинициализированных ссылках на объекты, в то время как Java HotSpot 10.0 делает –