Можно ли "исследовать", какие объекты определены в другом объекте, посредством отражения во время выполнения?

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

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 - объект AB
  • A$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 также использует тот же подход.

Другие вопросы по тегам