Java 什么是自动模块?

Java 什么是自动模块?,java,java-9,java-platform-module-system,java-module,Java,Java 9,Java Platform Module System,Java Module,自动模块在stackoverflow上被提到过很多次,但我找不到一个完整、简洁和自给自足的自动模块定义 那么,什么是自动模块?它出口所有的包裹吗?它能打开所有的包裹吗?它是否读取所有其他模块 是隐式定义的命名模块, 因为它没有模块声明。一个普通的命名模块, 相比之下,是显式定义的,带有模块声明;我们将 从今以后,将这些称为显式模块 使用它们的主要好处是,它们允许您在编译或运行时将工件视为模块,而无需等待它迁移到模块化结构 如果工件的主清单条目中有属性automatic module name,则

自动模块在stackoverflow上被提到过很多次,但我找不到一个完整、简洁和自给自足的自动模块定义

那么,什么是自动模块?它出口所有的包裹吗?它能打开所有的包裹吗?它是否读取所有其他模块

是隐式定义的命名模块, 因为它没有模块声明。一个普通的命名模块, 相比之下,是显式定义的,带有模块声明;我们将 从今以后,将这些称为显式模块

使用它们的主要好处是,它们允许您在编译或运行时将工件视为模块,而无需等待它迁移到模块化结构

如果工件的主清单条目中有属性automatic module name,则自动模块的模块名来自用于包含工件的JAR文件。模块名由JAR文件名派生而来


由于自动模块没有模块声明这一事实,实际上不可能判断它读取、打开或导出的所有模块或包

➜ 因此,由于没有针对驻留在自动模块中的包的显式导出/打开,描述为-

。。没有切实可行的方法来区分中的哪些包 自动模块供其他模块使用,或由 类仍然在类路径上。自动模块中的每个包 因此,被视为出口,即使它实际上可能是 仅供内部使用

➜ 进一步引用链接-

。。。没有切实可行的方法提前告诉你还有哪些模块 自动模块可能取决于。解析模块图后, 因此,会生成一个自动模块,以每隔一个指定的时间读取一次 模块,无论是自动的还是显式的

一个自动模块提供了传统级别的封装:所有包都是开放的,用于深度反射访问导出的,用于普通编译时和运行时访问其公共类型


➜ 另外,一个自动模块

授予所有其他自动模块隐含的可读性

由于这个原因,在一个模块中使用多个自动模块时

…无法确定其中一个出口 自动模块(x.y.z)中的包包含一个签名为 指在某些其他自动模块(a.b.c)中定义的类型

(关于缺少完整定义,您似乎是对的,因为我在语言或JVM规范中没有找到它)

Javadocs在
java.lang.module
包类中提供了大量的正式定义

部分引述自:

顶级目录中没有
模块info.class
的JAR文件定义了一个自动模块,如下所示:

  • 如果JAR文件在其主清单中具有属性“
    自动模块名
    ”,则其值为模块名。模块名是从JAR文件名派生的

和来自:

自动模块的模块描述符不声明任何依赖项(对
java.base
的强制依赖项除外),也不声明任何导出或打开的包。自动模块在解析期间接受特殊处理,以便读取配置中的所有其他模块。当在Java虚拟机中实例化一个自动模块时,它会读取每个未命名的模块,并被视为所有包都已导出并打开

编辑(2021):

Java语言规范中的这一部分有以下有趣的注释:

JavaSE平台区分显式声明的命名模块(即使用模块声明)和隐式声明的命名模块(即自动模块)。然而,Java编程语言并没有表现出这种区别:requires指令引用命名模块,而不考虑它们是显式声明的还是隐式声明的

虽然自动模块便于迁移,但它们不可靠,因为当作者将它们转换为显式声明的模块时,它们的名称和导出的包可能会更改。如果requires指令引用自动模块,则鼓励Java编译器发出警告。如果指令中出现可传递修饰符,建议发出特别强烈的警告


我首先回答您的实际问题(“什么是自动模块?”),但我也解释了它们的用途。很难理解为什么自动模块在没有这些信息的情况下会有这样的行为

什么是自动模块? 模块系统根据在模块路径上找到的每个JAR创建一个模块。对于模块化JAR(即带有模块描述符的JAR),它们的定义非常简单。对于普通JAR(没有模块描述符),这种方法不起作用,那么模块系统应该做什么呢?它会自动创建一个模块——可以说是一个模块——并对这三个属性进行最安全的猜测

名称 获取名称的过程分为两步:

  • 如果JAR在其清单中定义了
    自动模块名
    头,它将定义模块名
  • 否则,将使用JAR文件名来确定名称
第二种方法本质上是不稳定的,因此不应发布依赖于此类自动模块的模块

要求 由于普通JAR表示no requires子句,因此模块系统允许自动模块将所有其他模块读入(aka模块图)。与显式模块不同,自动模块还读取未命名模块,该模块包含