Java отражающие подклассы - PullRequest
       6

Java отражающие подклассы

2 голосов
/ 26 февраля 2010

У меня есть класс на Java, я хочу отразить все подклассы этого класса, как бы я это сделал?

В этом конкретном случае все подклассы находятся в одном пакете, и в этом пакете находятся только подклассы, поэтому эквивалентным решением является выборка всех классов в пакете.

Ответы [ 3 ]

2 голосов
/ 26 февраля 2010

Я думаю, вы могли бы сделать это, используя org.springframework.core.io.support.PathMatchingResourcePatternResolver * Spring. . По крайней мере, я знаю, что вы можете использовать его, чтобы найти все классы с определенной аннотацией. Поиск подклассов, похоже, очень похожая проблема, и я ожидаю, что она тоже сработает.

Вот некоторый (непроверенный) код для начала работы:

PathMatchingResourcePatternResolver match = new PathMatchingResourcePatternResolver();
MetadataReaderFactory f = new SimpleMetadataReaderFactory();
List<Class<?>> matches = ...;
for (Resource r : match.getResources("classpath*:com/example/**/*.class")) {
    AnnotationMetadata meta = f.getMetadataReader(r).getAnnotationMetadata();
    if (meta.getAnnotationsTypes().contains(MyAnnotation.class.getName()) {
        matches.add(Class.forName(meta.getClassName()));
    }
}
return matches;

Как вы можете видеть, это в основном идея, описанная Stephen C

1 голос
/ 26 февраля 2010

Это возможно сделать (беспорядочно) в некоторых случаях; например если классы вашего приложения загружаются из локальных каталогов или файлов JAR. По сути, вам нужно сопоставить имя пакета с путем и использовать API File и / или ZipFile для поиска файлов в соответствующем «каталоге», имя которого заканчивается на «.class». Затем вы используете Class.forName(), загружаете соответствующие классы (пытаясь избежать их инициализации) и используете clazz.isAssignableFrom(subclazz), чтобы увидеть, какие из них являются подклассами.

Но это не сработает во всех случаях. Одна из проблем заключается в том, что ClassLoader API не поддерживает итерацию по всем классам / пакетам, которые он может загрузить.

Я бы порекомендовал вам найти альтернативный подход к проблеме, которую вы пытаетесь решить.

РЕДАКТИРОВАТЬ - в ответ на этот комментарий.

Кажется, это серьезная ошибка в API отражения Java

Я понимаю, что упущение является преднамеренным. Если бы API загрузчика классов включал метод для предоставления всех классов в пакете, это ограничило бы схемы, которые можно использовать для загрузки классов. Например, URLClassLoader не может быть реализован для URL-адресов «http:», поскольку протокол HTTP не обеспечивает стандартный способ получения записей в каталоге.

Кроме того, есть несколько ситуаций, когда производственное приложение действительно должно рефлексивно найти все классы в пакете.

1 голос
/ 26 февраля 2010

См. этот ответ , как найти все классы в пакете.

Далее вам понадобится список всех пакетов, что в общем случае не тривиально. Но если вы используете только стандартный загрузчик классов (который зависит исключительно от пути к классам), вы можете получить системное свойство java.class.path и проанализировать его, чтобы получить все JAR-файлы. Откройте их, чтобы перечислить содержимое, и тогда вы узнаете имена классов.

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