2010-02-26 4 views
2

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

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

ответ

2

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

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

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

См. this answer как найти все классы в пакете.

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

1

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

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

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

EDIT - в ответ на этот комментарий.

Кажется, это массивная ошибка в Java Reflection API

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

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

+0

В конце концов, я сделал найти альтернативное решение, которое является бит беспорядок, но это лучше, чем любой из решений, которые я читал (например, этот). Похоже, что это массивная ошибка API-интерфейса java :( – Martin

+0

Я вижу вашу точку с ответом на мой комментарий. Хотя вы всегда можете подклассы Пакет с «searchablePackage», который позволяет перечислять и искать среди своих классов: P – Martin

+0

@Martin - Как бы вы его реализовали?Основная проблема заключается в том, что невозможно * реализовать * итерацию над загружаемыми классами в пакете ... без необходимости выполнять некоторые виды загрузчиков классов. –

Смежные вопросы