На жаль, Java не пропонує простий спосіб перерахування класів у "рідному" JRE. Це дає вам декілька варіантів: (a) для будь-якого файлу JAR ви можете перелічити записи всередині цього файлу JAR, знайти .class
файли та визначити, який клас Java .class
представляє кожен файл; або (b) ви можете використовувати бібліотеку, яка робить це за вас.
Варіант (a): Сканування файлів JAR вручну
У цьому варіанті ми заповнимо classNames
список усіх класів Java, що містяться у файлі jar на /path/to/jar/file.jar
.
List<String> classNames = new ArrayList<String>();
ZipInputStream zip = new ZipInputStream(new FileInputStream("/path/to/jar/file.jar"));
for (ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()) {
if (!entry.isDirectory() && entry.getName().endsWith(".class")) {
// This ZipEntry represents a class. Now, what class does it represent?
String className = entry.getName().replace('/', '.'); // including ".class"
classNames.add(className.substring(0, className.length() - ".class".length()));
}
}
Варіант (b): Використання спеціалізованих бібліотек відображень
Гуава
З тих ClassPath
пір Guava принаймні 14,0, що я використовував і любив. Одне приємне в тому ClassPath
, що він не завантажує знайдені класи, що важливо, коли ви скануєте велику кількість класів.
ClassPath cp=ClassPath.from(Thread.currentThread().getContextClassLoader());
for(ClassPath.ClassInfo info : cp.getTopLevelClassesRecurusive("my.package.name")) {
// Do stuff with classes here...
}
Роздуми
Я особисто не користувався бібліотекою Reflections , але це здається вподобаним. На веб-сайті наведено кілька чудових прикладів, як цей швидкий спосіб завантаження всіх класів у пакеті, наданому будь-яким файлом JAR, який також може бути корисним для вашої програми.
Reflections reflections = new Reflections("my.project.prefix");
Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class);