Можно ли "исследовать", какие объекты определены в другом объекте, посредством отражения во время выполнения?
Рассмотрим этот код:
object A {
object AA extends A
object AB extends A
object AC extends A
}; class A
Как можно "увидеть" объекты, определенные в объекте A
во время выполнения? Я думал, что метод в object A
с некоторым простым отражением кода было бы достаточно, но кажется, что компилятор выравнивает иерархию объектов во время компиляции и создал следующие файлы классов:
A.class
- класс АA$class
- сопутствующий объект АA$AA$.class
- объект ААA$AB$.class
- объект ABA$AC$.class
- объект переменного тока
После компиляции нет никаких признаков AA
, AB
или же AC
в сопутствующем объекте A
, который бы мой magicMethod
,
Кажется, что ClassLoader
У класса есть несколько методов, связанных с тем, что я планирую сделать, но все, похоже, ожидают точное строковое имя класса. Есть ли способ попросить ClassLoader найти все файлы классов, начиная с класса, из которого вызывается этот метод (A$
) на пути этого класса?
2 ответа
Код this.getClass.getDeclaredClasses
должен вернуть запрошенную информацию.
Но, немного поэкспериментировав с различными инструментами, он подозревает, что что-то здесь не работает правильно.
Я пробовал разные вещи в Scala с классами внутри классов, а не с объектами и исходными кодами Java, и, судя по поведению, он должен явно давать ожидаемые результаты, но в настоящее время это не так.
Либо я в корне не прав, либо scalac
возможно, вы забыли поместить некоторые биты метаданных в файлы классов, которые он генерирует, что приводит к неправильной информации об отражении.
Смотрите этот отчет об ошибке.
Основная проблема заключается в том, что у JVM нет понятия внутренних классов. Они были добавлены в Java 1.1, но спецификация JVM осталась полностью неизменной между 1.0 и введением invokedynamic (серьезно!).
Как хак, вы всегда можете разобрать имена классов и разделить на $
ОБНОВИТЬ
Для этого вам, к сожалению, придется сканировать путь к классам.
Одним из наиболее известных применений этой техники является Apache Commons Discovery: http://commons.apache.org/discovery/ (это то, что вы можете использовать, чтобы облегчить свою жизнь)
Spring также использует тот же подход.