Desafortunadamente, Java no proporciona una manera fácil de listar clases en el JRE "nativo". Eso le deja con un par de opciones: (a) para cualquier archivo JAR dado, puede enumerar las entradas dentro de ese archivo JAR, encontrar los .class
archivos y luego determinar qué clase Java .class
representa cada archivo; o (b) puede usar una biblioteca que lo haga por usted.
Opción (a): escanear archivos JAR manualmente
En esta opción, completaremos classNames
con la lista de todas las clases de Java contenidas dentro de un archivo jar en /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()));
}
}
Opción (b): uso de bibliotecas de reflexiones especializadas
Guayaba
Guava ha tenido ClassPath
desde al menos 14.0, que he usado y me ha gustado. Una cosa buena ClassPath
es que no carga las clases que encuentra, lo cual es importante cuando se busca una gran cantidad de clases.
ClassPath cp=ClassPath.from(Thread.currentThread().getContextClassLoader());
for(ClassPath.ClassInfo info : cp.getTopLevelClassesRecurusive("my.package.name")) {
// Do stuff with classes here...
}
Reflexiones
No he usado personalmente la biblioteca Reflections , pero parece muy apreciada. En el sitio web se proporcionan algunos ejemplos excelentes, como esta forma rápida de cargar todas las clases en un paquete proporcionado por cualquier archivo JAR, que también puede ser útil para su aplicación.
Reflections reflections = new Reflections("my.project.prefix");
Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class);