运行时资源以向后兼容的方式处理。例如。当你这样做的时候
URL url = Object.class.getResource("Object.class");
System.out.println(url);
在过去,你通常会得到类似的东西
jar:file:/path-to-jre/lib/rt.jar!/java/lang/Object.class
在 Java 9 下运行同样的程序会给你
jrt:/java.base/java/lang/Object.class
相反。无论哪种情况,您都可以在其上打开 FileSystem 以检查其他可用资源(自 Java 7 起)。虽然ZipFileSystem 必须首先通过FileSystems.newFileSystem 创建,但Java 9 的文件系统甚至已经开放使用:
private static void readMyOwnJRE() throws IOException {
try {
Path p = Paths.get(URI.create("jrt:/")).resolve("/modules");
System.out.println("My own JRE's modules:");
Files.list(p).forEach(m -> System.out.println(m.getFileName()));
System.out.println();
} catch(FileSystemNotFoundException ex) {
System.out.println("Could not read my modules (perhaps not Java 9?).");
}
}
如果您在与要检查的 JRE 不同的 JRE 下运行,则必须首先手动加载适当的文件系统实现,但这为检查 Java 9 安装提供了可能性,即使是从 Java 8 JRE 中检查:
public static void readOtherJRE(Path pathToJRE) throws IOException {
Path p = pathToJRE.resolve("lib").resolve("jrt-fs.jar");
if(Files.exists(p)) {
try(URLClassLoader loader = new URLClassLoader(new URL[]{ p.toUri().toURL() });
FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"),
Collections.emptyMap(),
loader)) {
System.out.println("Modules of "+pathToJRE);
Files.list(fs.getPath("/modules")).forEach(System.out::println);
System.out.println();
}
}
}
一旦你有了一个文件系统(或一个Path),你就可以使用所有的标准功能,例如Files 检查或提取/复制数据,尽管正确的术语是“将等效的类文件存储在不同的文件系统中”,因为运行时映像的表示根本不必是类文件。