Niestety Java nie zapewnia łatwego sposobu wyświetlania klas w „natywnym” środowisku JRE. To pozostawia kilka opcji: (a) dla dowolnego pliku JAR można wyświetlić listę wpisów w tym pliku JAR, znaleźć .class
pliki, a następnie określić, którą klasę Java .class
reprezentuje każdy plik; lub (b) możesz skorzystać z biblioteki, która zrobi to za Ciebie.
Opcja (a): Ręczne skanowanie plików JAR
W tej opcji wypełnimy classNames
listę wszystkich klas Java zawartych w pliku jar pod adresem /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()));
}
}
Opcja (b): Korzystanie ze specjalistycznych bibliotek odbić
Guawa
Guawa ma ClassPath
od co najmniej 14,0, którego używałem i lubiłem. Jedną z fajnych rzeczy ClassPath
jest to, że nie ładuje znalezionych klas, co jest ważne, gdy skanujesz w poszukiwaniu dużej liczby klas.
ClassPath cp=ClassPath.from(Thread.currentThread().getContextClassLoader());
for(ClassPath.ClassInfo info : cp.getTopLevelClassesRecurusive("my.package.name")) {
// Do stuff with classes here...
}
Refleksje
Osobiście nie korzystałem z biblioteki Reflections , ale wydaje się, że jest ona lubiana. Na stronie internetowej znajdują się świetne przykłady, takie jak szybki sposób załadowania wszystkich klas w pakiecie dostarczonym przez dowolny plik JAR, który może być również przydatny dla twojej aplikacji.
Reflections reflections = new Reflections("my.project.prefix");
Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class);