Вопрос-ответ

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

Как найти все подклассы данного класса в Java?

Как можно попытаться найти все подклассы данного класса (или всех разработчиков данного интерфейса) в Java? На данный момент у меня есть метод для этого, но я нахожу его довольно неэффективным (мягко говоря). Метод:


  1. Получить список всех имен классов, которые существуют в пути к классу

  2. Загрузите каждый класс и протестируйте, является ли он подклассом или разработчиком нужного класса или интерфейса

В Eclipse есть приятная функция, называемая иерархией типов, которая позволяет довольно эффективно отображать это. Как это сделать программно?

Переведено автоматически
Ответ 1

Поиск классов в чистой Java непросто.

Spring Framework предлагает класс под названием ClassPathScanningCandidateComponentProvider, который может делать то, что вам нужно. В следующем примере будут найдены все подклассы MyClass в пакете org.example.package

ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new AssignableTypeFilter(MyClass.class));

// scan in org.example.package
Set<BeanDefinition> components = provider.findCandidateComponents("org/example/package");
for (BeanDefinition component : components)
{
Class cls = Class.forName(component.getBeanClassName());
// use class cls found
}

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

Ответ 2

Нет другого способа сделать это, кроме того, что вы описали. Подумайте об этом - как кто-либо может узнать, какие классы расширяют ClassX, не сканируя каждый класс в classpath?

Eclipse может рассказать вам о super и подклассах только за то, что кажется "эффективным" промежутком времени, потому что у него уже есть все данные типа, загруженные в тот момент, когда вы нажимаете кнопку "Отобразить в иерархии типов" (поскольку он постоянно компилирует ваши классы, знает обо всем в пути к классам и т.д.).

Ответ 3

Это невозможно сделать, используя только встроенный Java Reflections API.

Существует проект, который выполняет необходимое сканирование и индексирование вашего пути к классу, чтобы вы могли получить доступ к этой информации...

Размышления


Анализ метаданных среды выполнения Java в духе Scannotations

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

Используя отражения, вы можете запросить свои метаданные для:



  • получить все подтипы некоторого типа

  • получить все типы, снабженные некоторой аннотацией

  • получить все типы, аннотированные некоторой аннотацией, включая соответствие параметров аннотации

  • получить все методы, аннотированные некоторыми


(отказ от ответственности: я его не использовал, но описание проекта, похоже, точно соответствует вашим потребностям.)

Ответ 4

Попробуйте ClassGraph. (Отказ от ответственности, я автор). ClassGraph поддерживает сканирование на наличие подклассов данного класса либо во время выполнения, либо во время сборки, но также и многое другое. ClassGraph может создавать абстрактное представление всего графа классов (все классы, аннотации, методы, параметры метода и поля) в памяти, для всех классов в classpath или для классов в выбранных пакетах, и вы можете запрашивать этот граф классов по своему усмотрению. ClassGraph поддерживает больше механизмов спецификации путей к классам и загрузчиков классов, чем любой другой сканер, а также без проблем работает с новой модульной системой JPMS, поэтому, если вы основываете свой код на ClassGraph, ваш код будет максимально переносимым. Смотрите API здесь.

java class