Вопрос по java, runtime, reflection – Можно ли получить все подклассы класса? [Дубликат]

17

Possible Duplicate:
How do you find all subclasses of a given class in Java?

Привет,

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

К сожалению, вопрос не о c #. Tom
Дублирование? «Как найти все подклассы данного класса в Java?»,stackoverflow.com/questions/492184/… Jonik
Вы также можете обратиться к другой старой статьеhere для получения более подробной информации, я считаю, это полезно для вас :) Paul Lo
этот вопрос больше ориентирован на шаблон загрузчика сервисов? dfa
В C # это можно сделать, выполнив итерацию по определению каждого класса в сборке и протестировав каждый из этих классов, чтобы увидеть, реализует ли он этот интерфейс. ChrisW

Ваш Ответ

8   ответов
-2

вы можете отсканировать путь к классам и найти подклассы «вручную».

0

поэтому я, вероятно, ошибаюсь. Для класса не имеет смысла иметь информацию о его потомках или подклассах, потому что в любой момент времени кто-то может создать новый подкласс вашего класса. Затем вам придется перекомпилировать свой класс, чтобы каждый раз включать эту новую информацию. Это не имеет смысла для расширяемого кода. Более вероятно, что класс содержит информацию о своих предках. Таким образом, единственное решение, которое я вижу, состоит в том, чтобы вы перебирали все классы в вашей области задач и проверяли, но это, скорее всего, ужасное решение для вас.

24

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

Вы не можете сделать это во время выполнения, но не можете найти классы до тех пор, пока они не будут загружены, и как вы узнаете, что они загружены? Вы можете сканировать каждый файл JAR и файл класса, но это не является окончательным. Плюс есть такие вещи, как загрузчики классов URL.

Внутренние классы (статические и нестатические) - это еще один случай, который следует рассмотреть. Именованные внутренние классы легче найти. Анонимные внутренние классы потенциально намного труднее найти.

Вы также должны учитывать, что если у класса есть подклассы, то новые подклассы могут быть созданы позже.

1

используя отражение. Прочитайте эту статью от JavaWorld

http://www.javaworld.com/javaworld/javatips/jw-javatip113.html

Этот код сканирует только конкретный пакет. Но подклассы могут существовать в любом пакете. В статье говорится: «нас интересуют все классы, которые реализуют данный интерфейс. Такая информация недоступна через Java Reflection & quot ;.
Я неправильно понял вопрос, статья выше предназначена только для поиска подклассов, которые реализуют данный интерфейс
1

которым вы сможете это сделать, - это пройти иерархию пакетов для пакетов, доступных в classpath, проверяя каждый класс с помощью отражения (и это будет отстой, потому что вы эффективно загрузите каждый класс, если вы не ограничите свой поиск определенные пакеты).

Проблема с этим типом автомагического поведения состоит в том, что становится трудно определить количество приложения без его запуска, что является головной болью при обслуживании. Я всегда предпочитаю идти по пути инъекции (а-ля Spring), пропуская экземпляры через какую-то конфигурацию.

0

которые реализуют определенный интерфейс, или перечислить классы, производные от некоторого базового класса? Это две разные проблемы. И то, и другое, насколько я знаю, будет трудно реализовать, поскольку новые реализации могут быть созданы / установлены на ПК в любое время в будущем. Похоже, вы пытаетесь создать фабричный метод для создания экземпляра определенного экземпляра, и вы не хотите жестко кодировать имя класса в коде. Обычно использование конфигурационного файла, который перечисляет все классы, которые реализуют интерфейс, - это путь (или можно использовать базу данных). Когда новые классы реализуют интерфейс, вы добавляете их в файл конфигурации, и фабрика должна подобрать имя нового класса.

5

ServiceLoader это встроенный класс. Он способен выполнять итерации во время выполнения для всех известных реализаций службы (интерфейса).

Если по какой-либо причине вы этого не хотите, вы можете использовать ClassLoader.getSystemResources () для перебора всех ресурсов; например если у вас есть 6 раз файл /META-INF/com.interface, вы получите 6 итераций.

1

добавить подкласс в путь к классам и победить ваши намерения. Подклассы - это открытое предложение.

Самое лучшее, что вы можете сделать, - это сказать, что для данного пути к классу вы знаете, что такое подклассы, и для этого вам нужно сканировать каждый класс в пути к классам.

Похожие вопросы