Sealed Packages/Jars和Java Module System都不允许在多个jar中拆分包。这是否意味着模块中包含的所有包都是隐式密封的?如果不是,明确地密封罐子会改变什么?
是的,模块中的包总是隐式密封的。这是在Package
类的文档中指定的:
为命名模块中的类自动定义的
Package
具有以下属性:
- 包的名称来源于类的二进制名称。由于命名模块中的类必须位于命名包中,因此派生名称永远不能为空。
- 包被密封,模块位置作为代码源,如果知道。
- 规范和实现标题、版本和供应商未指定。
- 包上的任何注释都是从上面指定的
package-info.class
中读取的。
我还做了一个快速测试来验证模块包上的isSealed()
确实返回true
。但是,必须注意的是,(命名的)模块和包之间的关系具有基本性质,因此与isSealed()
返回true
的事实无关。后者是旧API与新特性交互的自然方式。
未命名模块的密封包只影响特定类装入器的运行时包,因为每个类装入器可以有一个同名的包,这被认为是不同的运行时包。
相反,命名模块的每个包必须明确地属于整个模块层中的单个模块,并且模块层可以跨越多个类加载器,例如引导层跨越引导加载器,平台加载器和应用程序加载器。
这会影响类加载过程。旧的加载方式仍然用于未命名模块,其特点是类装入器委托,其中每个装入器首先查询其父装入器。当父加载器失败时,将线性查询类的类路径条目,直到找到一个类。
当一个模块层被初始化时,所有的包名和它们所属的模块都被记录下来,所以当尝试加载一个类时,包名可以从限定名中派生出来,甚至在类被加载之前就可以映射到模块上,因此,只需要查询模块的已知源。