什么是自动模块?

在stackoverflow上多次提到自动模块,但是我找不到自动模块的完整,简洁和自足的定义。

那么,什么是自动模块?是否导出所有软件包?是否打开所有包装?它会读取所有其他模块吗?

回答:

我首先回答您的实际问题(“什么是自动模块?”),但我还要解释它们的 用途 。很难理解为什么自动模块在没有这些信息的情况下会表现出自己的方式。

什么是自动模块?

模块系统根据在模块路径上找到的每个JAR创建一个模块。对于模块化JAR(即具有模块描述符的JAR),因为它们定义了模块的属性(名称,需求,导出),所以很简单。对于普通的JAR(无模块描述符),此方法不起作用,那么模块系统应该怎么做?它会自动创建一个模块-

可以说是一个自动模块 -并对这三个属性进行最安全的猜测。

回答:

得出名称的过程分为两个步骤:

  • 如果JAR Automatic-Module-Name在清单中定义了标头,则它定义了模块的名称
  • 否则,将使用JAR文件名来确定名称

第二种方法本质上是不稳定的,因此不应发布任何依赖于这种自动模块的模块。Maven对此警告。

回答:

由于普通JAR不表达require子句,因此模块系统允许自动模块读取将其放入可读性图(也称为模块图)中的所有其他模块。与显式模块不同,自动模块还会读取未命名的模块,该模块包含从类路径加载的所有内容。这个看似很小的细节非常重要(请参阅下文)。

自动模块还有一些可读性方面的古怪之处:

  • 第一个自动模块解决后,所有其他模块也将解决。这意味着一旦模块路径上的单个普通JAR被另一个模块引用,所有普通JAR都将作为自动模块加载。
  • 自动模块意味着在所有其他自动模块上均具有可读性,这意味着读取其中一个模块的模块将读取所有这些模块。

综上所述,这可能会产生不幸的效果,即依赖于几个普通JAR的显式模块(即非自动模块)可以只需要其中一个就可以摆脱(只要其他模块也都位于模块路径上) 。

回答:

由于JAR不包含哪些软件包被视为公共API以及哪些软件包未被视为公共API的信息,因此模块系统将导出所有软件包,并打开它们以进行深层思考。

回答:

模块系统还扫描META-INF/services并使自动模块提供其中命名的服务。假定自动模块允许使用所有服务。

最后,Main-Class清单条目也得到处理,因此可以启动定义一个清单的纯JAR,就像自动模块一样,其中使用jar工具(即java

--module-path my-app.jar --module my.app)设置了主类。

回答:

创建自动模块后,将其视为任何其他模块。这明确包括模块系统检查它是否为其他任何模块,例如拆分包。

什么是自动模块

引入模块的原因之一是使编译和启动应用程序更可靠,并更快地发现类路径可能的错误。requires条款的一个关键方面。

为了确保它们的可靠性,模块声明除了命名模块(没有从类路径中加载的所有内容)外,没有其他要求。如果故事到此结束,则模块化JAR只能依赖于其他模块化JAR,这将迫使生态系统从下至上进行模块化。

但是,这是不可接受的,因此引入了自动模块作为模块化JAR依赖非模块化模块的一种方式,为此,您需要做的就是将普通JAR放在模块路径上,并以模块系统的名称进行命名给它。

有趣的一点是,因为自动模块读取了未命名的模块,所以将其依赖项保留在类路径上是可行的(我通常建议这样做)。这样,自动模块充当了从模块到类路径的桥梁。

您的模块可以位于一侧,需要它们的直接依赖关系作为自动模块,而间接依赖关系可以保留在另一侧。每当您的一个依赖项变成一个显式模块时,它就将桥留在模块化侧,并将其直接依赖项作为自动模块绘制到桥上。

以上是 什么是自动模块? 的全部内容, 来源链接: utcz.com/qa/407141.html

回到顶部