Можно ли «исследовать», какие объекты определены в другом объекте, путем отражения во время выполнения? - PullRequest
2 голосов
/ 22 ноября 2010

Рассмотрим этот код:

object A {
  object AA extends A
  object AB extends A
  object AC extends A
}; class A

Как можно «увидеть» объекты, определенные в объекте A во время выполнения? Я думал, что метода внутри object A с некоторым простым кодом отражения будет достаточно, но кажется, что компилятор выравнивает иерархию объектов во время компиляции и создал следующие файлы классов:

  • A.class - класс А
  • A$class - Сопутствующий объект A
  • A$AA$.class - объект АА
  • A$AB$.class - объект AB
  • A$AC$.class - объект переменного тока

После компиляции нет никаких признаков около AA, AB или AC в сопутствующем объекте A, который имел бы мой magicMethod.

Кажется, что у класса ClassLoader есть некоторые методы, связанные с тем, что я планирую сделать, но все, похоже, ожидают точное строковое имя класса. Есть ли способ попросить ClassLoader найти все файлы классов, начиная с класса, из которого этот метод вызывается (A$) по пути к этому классу?

Ответы [ 2 ]

3 голосов
/ 22 ноября 2010

Основная проблема заключается в том, что у JVM нет понятия внутренних классов. Они были добавлены в Java 1.1, но спецификация JVM осталась полностью неизменной между 1.0 и введением invokedynamic (серьезно!).

Как хак, вы всегда можете разобрать имена классов и разделить на $

UPDATE

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

Одним из наиболее известных применений этой техники является Apache Commons Discovery: http://commons.apache.org/discovery/ (это то, что вы можете использовать, чтобы облегчить свою жизнь)

Spring также использует тот же подход.

1 голос
/ 23 ноября 2010

Код this.getClass.getDeclaredClasses должен возвращать запрошенную информацию.

Но, немного поэкспериментировав с различными инструментами, он подозревает, что что-то здесь работает неправильно.

Я пробовал разные вещи в Scala с классами внутри классов вместо объектов и исходных кодов Java, и, судя по поведению, он должен явно возвращать ожидаемые результаты, но в настоящее время это не так.

Либо яЯ в корне ошибочен, или scalac может забыть вставить некоторые биты метаданных в файлы классов, которые он генерирует, что приведет к неверной информации об отражении.

См. этот отчет об ошибке .

...