Thật không may, Java không cung cấp một cách dễ dàng để liệt kê các lớp trong JRE "bản địa". Điều đó khiến bạn có một số tùy chọn: (a) đối với bất kỳ tệp JAR nào đã cho, bạn có thể liệt kê các mục nhập bên trong tệp JAR đó, tìm các .class
tệp và sau đó xác định mỗi lớp Java.class
tệp đại diện; hoặc (b) bạn có thể sử dụng một thư viện thực hiện việc này cho bạn.
Tùy chọn (a): Quét tệp JAR theo cách thủ công
Trong tùy chọn này, chúng tôi sẽ điền vào classNames
danh sách tất cả các lớp Java có bên trong tệp jar tại /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()));
}
}
Lựa chọn (b): Sử dụng thư viện phản ánh chuyên biệt
Trái ổi
Ổi đã có ClassPath
từ ít nhất 14.0, mà tôi đã sử dụng và thích. Một điều thú vị ClassPath
là nó không tải các lớp mà nó tìm thấy, điều này rất quan trọng khi bạn đang quét một số lượng lớn các lớp.
ClassPath cp=ClassPath.from(Thread.currentThread().getContextClassLoader());
for(ClassPath.ClassInfo info : cp.getTopLevelClassesRecurusive("my.package.name")) {
// Do stuff with classes here...
}
Suy ngẫm
Cá nhân tôi chưa sử dụng thư viện Reflections , nhưng nó có vẻ rất được yêu thích. Một số ví dụ tuyệt vời được cung cấp trên trang web như cách nhanh chóng này để tải tất cả các lớp trong một gói được cung cấp bởi bất kỳ tệp JAR nào , điều này cũng có thể hữu ích cho ứng dụng của bạn.
Reflections reflections = new Reflections("my.project.prefix");
Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class);