Как JVM может решить, принадлежит ли класс (например, внутренние или вложенные классы) другому классу? - PullRequest
6 голосов
/ 10 ноября 2011

Я хочу немного лучше понять файлы классов и внутренние / вложенные классы, и мне интересно следующее:

  • Используется ли атрибут InnerClasses для ссылки на внутренние / вложенные классы в классе «Содержащий», или он используется во внутренних / вложенных классах для ссылки на класс «контейнер»?
  • Достаточно ли атрибута InnerClasses в файлах классов? Например. Должны ли внутренние / вложенные классы следовать за искажением имени с $ или это просто соглашение?
  • Есть ли способ сделать класс похожим на внутренний / вложенный класс для JVM без установки атрибута InnerClasses, и зависит ли это от поставщика JLM? (Я помню, что слышал, что у реализации IBM в некоторых частях были менее строгие требования.)
  • Насколько механизм загрузки классов JVM взаимодействует с отражением Java? Можно ли заставить JVM не соглашаться с результатами рефлексии Java?

Я попытался найти его в спецификации JVM, но не нашел описания действующего механизма.

Я нашел это предложение только в «Атрибут InnerClasses» , удаленно связанный с моим вопросом:

Виртуальная машина Java в настоящее время не проверяет согласованность атрибут InnerClasses с любым файлом класса, фактически представляющим класс или интерфейс, на который ссылается атрибут.

Ответы [ 2 ]

2 голосов
/ 24 февраля 2012

Несколько дополнений к предыдущему ответу:

Используется ли атрибут InnerClasses для хранения содержащихся внутренних / вложенных классов в содержащем классе, или он используется во внутренних / вложенных классах для ссылки на класс «container»?

Байт-код каждого скомпилированного класса хранится в отдельном файле .class. Фактические «внутренние классы» не хранятся в этом атрибуте. Как указывалось в предыдущем посте, этот атрибут указывает только на классы, о которых знал компилятор при создании байт-кода.

Достаточно ли атрибута InnerClasses в файлах классов? Например. Должны ли внутренние / вложенные классы следовать за изменением имени с помощью $ или это просто соглашение?

Есть ли способ сделать класс похожим на внутренний / вложенный класс для JVM без установки атрибута InnerClasses, и зависит ли это от поставщика JLM? (Я помню, что слышал, что у реализации IBM в некоторых частях были менее строгие требования.)

По обоим вопросам я не уверен. Но я думаю, что концепция внутренних / вложенных классов - это то, что язык Java (и, следовательно, обеспечивает компилятор Java). В байт-коде не должно быть никакой разницы между классом, который был объявлен как обычный открытый класс, и некоторым вложенным или внутренним классом. Вы можете легко проверить, как данная виртуальная машина справляется с этим следующим образом:

  • Создать класс с несколькими вложенными и внутренними классами
  • Напишите небольшую программу, которая пытается загрузить и создать один из внутренних классов посредством отражения вне области определения класса. Вы должны использовать отражение здесь, потому что компилятор Java не позволит вам создать экземпляр вложенного класса, который находится вне области видимости! Если вы можете успешно создать экземпляр класса, это свидетельствует о том, что внутренне виртуальная машина не обрабатывает вложенные и обычные классы по-разному.

Насколько механизм загрузки классов JVM взаимодействует с отражением Java? Можно ли заставить JVM не соглашаться с результатами рефлексии Java?

Я не понимаю этот последний вопрос. Не могли бы вы объяснить немного больше, что вы имеете в виду, когда говорите, что виртуальная машина и рефлексия не согласны?

1 голос
/ 10 ноября 2011

Я знаю, что в файлах классов есть внутренний атрибут класса, но достаточно ли этого?

Атрибут InnerClasses находится в байтовом коде и перечисляет все известные внутренние классы внешнего класса. Это не то, что вы можете использовать напрямую.

например. Должны ли внутренние / вложенные классы следовать за изменением имени с помощью $ или это просто соглашение?

Компилятор будет следовать этому соглашению, и вы не сможете его контролировать.

Есть ли способ сделать класс похожим на внутренний / вложенный класс для JVM без установки атрибута внутреннего класса, и зависит ли это от поставщика JLM? (Я помню, что слышал, что у реализации IBM в некоторых частях были менее строгие требования.)

Вы можете создать класс с тем же именем. Вы можете попробовать это сами.

Насколько механизм загрузки классов JVM взаимодействует с отражением Java?

Я не верю, что загрузчик классов использует отражение. Однако отражение может получить информацию из того же места, что и загрузчик классов. Я не понимаю, почему это важно.

Можно ли заставить JVM не соглашаться с результатами рефлексии Java?

Вы можете использовать отражение, чтобы повредить данные в объектах на основе отражения. Опять же, не знаю, почему вы хотите это сделать.

...