Package java.lang.module
除非另有说明,否则将null
参数传递给此程序包中任何类或接口的构造函数或方法将导致抛出NullPointerException
。 另外,除非另有说明,否则调用包含null
元素的数组或集合的方法将导致一个NullPointerException
。
Resolution
分辨率是计算模块如何相互依赖的过程。 该过程发生在编译时和运行时。
分辨率是一个两步的过程。 第一步递归地枚举一组根模块的“require”指令。 如果所有枚举的模块都是可观察的,则第二步计算其可读性图。 可读性图表示了模块如何相互依赖,从而控制跨模块边界的访问。
步骤1:递归枚举
递归枚举采用一组模块名称,查找每个模块声明,对于每个模块声明,递归枚举:
'require'指令与'传递'修饰符给出的模块名称,以及
在主机系统的判断下,由“require”指令给出的模块名称没有“传递”修饰符。
模块声明在一组可观察模块中查找。 可视化模块的集合以实现特定的方式确定。 可观察模块的集合可以包括具有明确声明的模块(即,具有module-info.java
源文件或module-info.class
文件)和具有隐式声明的模块(即automatic modules )。 因为一个自动模块没有明确的模块声明,所以它没有自己的'require'指令,尽管它的名字可以由显式模块声明的'requires'指令给出。
根据模块的名称作为该算法的初始输入,根据实现特定的方式确定。 该组模块可以包括自动模块。
如果至少有一个自动模块被这个算法枚举,那么每个可观察的自动模块都必须被枚举,无论他们的名字是否由显式模块声明的'require'指令给出。
如果发生以下任何一种情况,则解决方法失败:
任何根模块都不可观察。
名称由“要求”指令与“传递”修饰符赋予的任何模块都不可观察。
由主机系统决定,任何名称由“require”指令而不带“传递”修饰符的模块都不可观察。
此步骤中的算法枚举了相同的模块名称两次。 这表示'require'指令中的一个循环,忽略任何'传递'修饰符。
否则,决议进入步骤2。
步骤2:计算可读性图
'require'指令(不管'传递')表示一个模块依赖于其他模块。 “传递”修饰符的作用是使附加模块也依赖于其他模块。 如果模块M'需要传递性N',那么M不仅取决于N,而且取决于M的任何模块也取决于N。这允许M被重构,使得其内容的一些或全部可以被移动到新的模块N不会破坏具有'require M'指令的模块。
模块依赖性由可读性图表示。 可读性图是一个有向图,其顶点是在步骤1中列举的模块,其边缘表示模块对之间的可读性。 边缘的规定如下:
首先,可读性由枚举模块的“require”指令决定,忽略任何“传递”修饰符:
对于每个需要“B:A”的枚举模块A,读取“B.
对于自动的每个枚举模块X:X“读取”每隔一个枚举的模块(这就像“自动模块对每个其他枚举模块都有”require“指令)一样。
第二,可读性被增加以考虑“传递性”修饰符:
对于每个列举的模块A,“读取”B:
如果B'需要传递'C',那么A“读取”C“以及”B“。这个扩展是递归的:因为A”读取“C”,如果C'需要传递'D',那么A“读取”D“以及”C“ B.
如果B是自动模块,则A“读取”每隔一个枚举的自动模块。 (“仿佛”自动模块对每个其他枚举的自动模块都有“需要传递”指令)。
最后,每个模块“读”本身。
如果可读性图中出现以下任何一种情况,则解析失败:
模块“读取”两个或多个具有相同名称的模块。 这包括模块“读”另一个与其自身名称相同的情况。
两个或多个模块将具有相同名称的包导出到“读取”两者的模块。 这包括包含包p的模块M“读取”将p导出到M的另一个模块的情况。
模块M声明它使用pS'或'提供pS与...',但是包p不是模块M,也不会由M“读取”的任何模块导出到M。
否则,分辨率成功,解析结果是可读性图。
根模块
编译时根组件通常是正在编译的一组模块。 在运行时,根组件通常是指定给“java”启动器的应用程序模块。 当在未命名的模块中编译代码时,或者在从类路径加载主应用程序类时的运行时,默认的根模块是实现特定的(在JDK实现中它是模块“java.se”,如果可观察,以及导出API的每个可观察模块)。
可观察模块
编译时和运行时的可观察模块可以通过搜索几个不同的路径,也可以通过搜索内置到环境中的编译模块来确定。 搜索顺序如下:
在编译时只有编译模块的路径。 此路径包含源代码形式的模块定义。
升级模块路径。 该路径包含模块的编译定义,优先于(3)和(4)中存在的任何可升级模块的编译定义。 请参阅Java SE平台,指定哪些标准模块可升级。
系统模块是内置于环境中的编译定义。
应用程序模块路径。 此路径包含库和应用程序模块的编译定义。
'require'指令与'static'修饰符
'require'指令具有'static'修饰符在运行时表达可选依赖。 如果模块声明它需要静态M',那么分辨率不会搜索可观察模块M以满足依赖性。 然而,如果在步骤1中递归地枚举M,那么枚举的所有模块和“需要静态M”将读取M.
完整性
解决方案在编译时可能是部分的,因为完整的传递闭包可能不需要编译一组模块。 最小程度上,在编译时构建和验证的可读性图包括正在编译的模块,它们的直接依赖关系以及所有隐式声明的依赖性(需要传递)。
在运行时,分辨率是一个加法过程。 步骤1中的递归枚举可能与先前的分辨率相关,因此当由以前(或父级)分辨率枚举时,不会枚举根模块或“require”指令中命名的模块。 因此,作为分辨率结果的可读性图可以具有在步骤1中枚举的模块的顶点,但是具有表示模块读取由先前(或父级)分辨率枚举的模块的边缘。
- 从以下版本开始:
- 9
-
接口摘要 接口 描述 ModuleFinder 模块的取景器。ModuleReader 提供访问模块的内容。 -
类摘要 Class 描述 Configuration 的构造的结果是 resolution或分辨率 service binding 。ModuleDescriptor 模块描述符。ModuleDescriptor.Builder 构建ModuleDescriptor
对象的构建器。ModuleDescriptor.Exports 由模块导出的包可能有资格或不合格。ModuleDescriptor.Opens 由模块打开的包可能有资格或不合格。ModuleDescriptor.Provides 模块提供一个或多个实现的服务。ModuleDescriptor.Requires 对模块的依赖ModuleDescriptor.Version 模块的版本字符串。ModuleReference 参考模块的内容。ResolvedModule 解析模块图中的 模块 。 -
枚举摘要 Enum 描述 ModuleDescriptor.Exports.Modifier 导出包上的修饰符。ModuleDescriptor.Modifier 模块上的修饰符。ModuleDescriptor.Opens.Modifier 打开包装上的修饰符。ModuleDescriptor.Requires.Modifier 模块依赖的修饰符。 -
异常摘要 异常 描述 FindException 抛出一个ModuleFinder
发生错误时发现一个模块。InvalidModuleDescriptorException 读取模块描述符时抛出,并且发现模块描述符格式不正确或不能解释为模块描述符。ResolutionException 在解析一组模块或解析一组具有服务绑定的模块时抛出失败。