需枚舉 `java.io` 包下所有類/接口,核心思路:定位 JRE 安裝路徑 → 讀取 `jre/lib/rt.jar` (JDK 8) 或 `jmods/java.base.jmod` (JDK 9+) → 過濾包前綴。
public static Set<String> listClassesInJavaIo() throws IOException {
String javaHome = System.getProperty("java.home"); // .../jre
Path rtJar = Paths.get(javaHome, "lib", "rt.jar");
Set<String> classes = new HashSet<>();
try (JarFile jar = new JarFile(rtJar.toFile())) {
jar.stream()
.filter(je -> !je.isDirectory())
.map(je -> je.getName().replace('/', '.'))
.filter(name -> name.startsWith("java.io.") && name.endsWith(".class"))
.map(name -> name.substring(0, name.length() - 6)) // 去 .class
.forEach(classes::add);
}
return classes;
}
jmod list java.base.jmod 命令行工具,或解析 JMOD 格式(較複雜)。ClassLoader.getSystemResources("java/io/") 只能獲取資源文件,無法枚舉類。<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.10.2</version>
</dependency>
Reflections reflections = new Reflections("java.io");
Set<Class<?>> classes = reflections.getSubTypesOf(Object.class); // 包含接口
注意:模塊化後需 `--add-opens java.base/java.io=ALL-UNNAMED` 才能反射訪問非導出包。