模块:Java 9 中引入的一种新的语言特性(类似于类、接口、包等),它由一组包组成,类似于包由类型集合组成的方式。
JAR:一种归档文件格式,它捆绑了代码和资源,可以由 JVM 加载。
更具体地说,模块定义如下:
为了提供可靠的配置和强大的封装,以一种既能为开发人员所接近又能得到现有工具链支持的方式,我们将模块视为一种基本的新型Java程序组件。模块是代码和数据的命名、自描述集合。它的代码被组织成一组包含类型的包,即Java类和接口;其数据包括资源和其他类型的静态信息。
...
模块的自我描述在其模块声明中表示,这是Java编程语言的一种新构造。
...
按照惯例,模块声明被编译成一个名为 的文件,该文件以类似方式放置在类文件输出目录中。
module-info.class
模块可以编译成 Jar 文件,在这种情况下,Jar 文件被标记为模块化 Jar 文件:
现有工具已经可以创建、操作和使用 JAR 文件,因此为了便于采用和迁移,我们定义了模块化 JAR 文件。模块化 JAR 文件在所有可能的方式上都类似于普通的 JAR 文件,只是它还在其根目录中包含一个文件。
module-info.class
模块和 JAR 之间的一些其他区别:
-
模块可能需要其他模块,以便允许需要的模块访问依赖类。Jar 没有这样的依赖概念。
-
模块可以决定将哪些类和接口导出到需要它的其他模块。Jar 没有这样的封装机制。
-
一个模块可以编译成一个模块化的Jar文件,但一些模块(例如JDK模块)被编译成另一种称为JMOD的格式。
-
可以更改 JAR 的名称。只要 JVM 类装入器在类路径上找到所需的类(它可以由单个 JAR、多个 JAR 组成,或者由目录或 JAR 之间的混合组成),JAR 文件的名称可以是任何内容。但是,一个模块的名称可以在其他模块的声明中显式引用,并且这样的名称定义了它,并且不能自由更改。
严格来说,模块是一个运行时概念。正如其他人从模块系统的状态中引用的那样:
模块是代码和数据的命名、自描述集合。它的代码被组织成一组包含类型的包,即Java类和接口;其数据包括资源和其他类型的静态信息。
这与 JAR 非常相似,但是...
- JAR 在运行时没有有意义的表示形式
- JAR不是“自描述的”,在这种情况下,这意味着它们没有JVM关心的名称,无法表达依赖关系或定义适当的API
这就留下了一个问题,模块来自哪里?有多种方法,但对于开发人员来说,最突出的一种是模块化JAR。模块化 JAR 就像普通的 JAR 一样,但它包含一个模块描述符,一个从 编译而来的文件。正是该文件定义了模块的名称、依赖项和 API。module-info.class
module-info.java
因此,JAR和模块之间存在很强的联系:JAR是模块系统创建模块的容器,并且(目前)每个JAR只能包含一个模块。重要的是要注意,即使在Java 9上,JAR也不必是模块化的 - 普通的JAR是完全没问题的。
-
如何使用Java中的RESTful Web服务获取远程/客户端IP地址? 我已经在我的项目中编写了Rest Web服务。Web服务调用可能来自不同 machine.so 我需要通过REST Web服务找出IP地址。 从这个请求.getRemoteAddr()使用这个。 但是我不能使用getRemoteAddr()。因为我的请
-
从包含大量文件的zip文件中提取1文件的最快方法是什么? 我尝试了但它们也缺少一些东西。 LZMA SDK不提供一种如何使用的文档/教程,这非常令人沮丧。没有 javadoc。 虽然7z jbinding没有提供一种简单的方法来只提取1个文件,但是,它只提供了提取zip文件
-
输入/输出流在销毁时是否关闭? Java 中的 InputStreams 和 OutputStreams 是否在销毁时关闭()?我完全理解这可能是不好的形式(特别是在C和C++世界中),但我很好奇。 另外,假设我有以下代码: 无名的FileInputStream是否在p.load
-
Java 程序中的字符串大小是否有任何限制? 我有一个字符串定义为 字符串 xx 我可以分配的字符数是否有任何限制? 2) 我正在将用户输入分配给此字符串 xx。70%的人只说一个字。有时他们给出一个大句子,所以想知道可
-