น่าเสียดายที่ 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
ตั้งแต่อย่างน้อย 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);