一个模块和一个ClassLoader之间的关系是什么?
每个模块都有自己独特的ClassLoader吗?
如何在一个模块中获取所有的类?
发布于 2022-06-08 12:28:42
模块由单个类加载器加载,但类加载器可能负责任意数量的模块。
内置模块都由一个或两个类装入器、引导类加载器和平台类加载器加载。启动时指定的应用程序特定模块都由系统类加载器(也称为应用程序类加载器)加载。这三个内置类装载机加载属于启动层的所有模块的类
当您创建一个新的模块层时,您可以要求它的每个模块使用一个方便法由一个不同的类加载器来加载,但是请求单个加载程序加载所有模块的是同样简单。有一个取函数的方法将每个模块名称映射到一个类加载器,允许像引导层这样更详细的设置,但是它仍然将一个特定的模块映射到一个加载程序。因此,正如在开始时所说的,一个模块将由一个加载程序加载,但一个加载程序可能负责多个模块。
Java中的类加载仍然是动态的,所以我们不能确定一个模块中有多少类,但是属于一个模块的包是固定的。这样您就可以轻松地查询这些包了。
Module m = Object.class.getModule(); // java.base
// using java.compiler as an example with not so many packages
m = m.getLayer().findModule("java.compiler").orElseThrow();
m.getPackages().forEach(System.out::println);
javax.lang.model
javax.lang.model.type
javax.tools
javax.lang.model.util
javax.lang.model.element
javax.annotation.processing
您可以查询模块的存储中现有的类文件,这可能会给出模块中可能存在的类的估计值,但如上所述,类加载是动态的,因此在运行时可能会有更多的类,而不是持久的存储。
List<String> classNames;
try(var reader = m.getLayer().configuration()
.findModule(m.getName()).orElseThrow().reference().open()) {
classNames = reader.list()
.filter(s -> s.endsWith(".class"))
.map(s -> s.substring(0, s.length() - ".class".length()).replace('/', '.'))
.toList();
}
classNames.forEach(System.out::println);
https://stackoverflow.com/questions/72412555
复制相似问题