Java 9 - "模块"和"JAR"文件有什么区别?

Nee*_*ain 21 java jar java-9 java-module

我正在从Java9的What's New中学习Java 9,讨论的热门话题之一是 模块化JDK.

我有些疑惑:

  1. JAR文件是模块吗?
  2. 模块与JAR文件有何不同?

man*_*uti 17

模块:一个新的语言在Java中9(类似于类,接口,包等)推出的功能,包括包,类似一个包如何由一个类型的集合的集合.

JAR:一种归档文件格式,它捆绑代码和资源,可以由JVM加载.

更具体地,模块定义如下:

为了以一种既可供开发人员使用又可由现有工具链支持的方式提供可靠的配置和强大的封装,我们将模块视为一种基本的新型Java程序组件.一个模块是代码和数据的命名,自描述的集合.它的代码被组织为一组包含类型的包,即Java类和接口; 其数据包括资源和其他类型的静态信息.

...

模块的自描述在其模块声明中表示,模块声明是Java编程语言的新结构.

...

按照惯例,模块声明被编译到一个名为的文件中module-info.class,类似地放在类文件输出目录中.

可以将模块编译为Jar文件,在这种情况下,Jar文件标记为模块化Jar文件:

现有工具已经可以创建,操作和使用JAR文件,因此为了便于采用和迁移,我们定义了模块化JAR文件.模块化JAR文件在所有可能的方式都像普通的JAR文件,除了它module-info.class在根目录中还包含一个文件.

模块和JAR之间的一些其他差异:

  1. 模块可以要求其他模块,以允许需求模块访问依赖类.Jar没有这样的依赖概念.

  2. 模块可以决定将哪些类和接口导出到需要它的其他模块.Jar没有这样的封装机制.

  3. 模块可以编译成模块化的Jar文件,但是一些模块(例如JDK模块)被编译成另一种称为JMOD的格式.

  4. 可以更改JAR的名称.只要JVM类加载器在类路径上找到所需的类(可以由单个JAR,多个JAR或目录或JAR之间的混合组成),JAR文件的名称就可以是任何名称.但是,模块的名称可以在其他模块的声明中显式引用,并且这样的名称定义它并且不能自由更改.

  • `模块是一个命名的,自描述的代码和数据集合,对于JAR文件也是如此,对吧?JAR有一个名称,它是自包含的代码集合. (4认同)
  • @NeerajJain是的,但JAR不是语言或JVM元素.此外,它没有"要求"其他JAR或为其包含的代码提供访问控制的概念.可以认为模块与包类似,但它不包含类和接口,而是包含可以被其他模块访问的包. (2认同)

Nic*_*lai 9

严格来说,模块是运行时概念.正如其他人引用了"模块状态"系统:

模块是一个命名的,自描述的代码和数据集合.它的代码被组织为一组包含类型的包,即Java类和接口; 其数据包括资源和其他类型的静态信息.

这与JAR非常相似,但......

  1. JAR在运行时没有有意义的表示
  2. JAR不是"自我描述",在这种情况下意味着它们没有JVM关心的名称,无法表达依赖关系或定义适当的API

这就留下了问题,模块来自何处?有多种方式,但开发人员最突出的方法是模块化JAR.一个模块化的JAR就像一个普通JAR,但它包含一个模块描述符,文件module-info.class是由编译module-info.java.该文件定义了模块的名称,依赖关系和API.

因此,JAR和模块之间存在强大的联系:JAR是模块系统从中创建模块的容器,并且(目前)每个JAR只能包含一个模块.需要注意的是,即使Java的9个JAR文件并不重要的是必须是模块化的-普通的JAR文件是完全的罚款.


Nam*_*man 7

JAR文件是模块吗?模块与JAR文件有何不同?

不,Java Archive不是模块.

仅举一个例子,虽然同一个包的可以分布在JAR中,但现在无法从多个模块中读取相同的包.

一个JAR是一种文件格式,使您可以将多个文件打包成一个档案文件.通常,这包含与applet和应用程序关联的类文件和辅助资源.

另一方面(我试着在这里描述〜> )

一个模块是代码和数据的命名,自描述的集合.它的代码被组织为一包含类型的包,即Java类和接口; 其数据包括资源和其他类型的静态信息.

这也包括在帮助下指定的模块声明module-info.java.

每个模块定义都是

  • 模块伪影,即模块化JAR文件或文件JMOD含有已编译的模块的定义,否则

  • 一个分解模块目录,按照惯例,其名称是模块的名称,其内容是与包层次结构对应的"展开"目录树.

正如模块系统所介绍的,模块化图像由模块而不是JAR文件组成.对于模块化WAR文件,动态配置也可以预见模块化.


但对于易于采用的模块一个模块的JAR文件,在JDK9引入,这样可以说对于由一个模块module-info.java,使得

module com.foo.bar { }
Run Code Online (Sandbox Code Playgroud)

和其他java类一样

com/foo/bar/alpha/AlphaFactory.java
com/foo/bar/alpha/Alpha.java
Run Code Online (Sandbox Code Playgroud)

现有工具已经可以创建,操作和使用JAR文件.一个模块化的JAR文件就像在所有可能的方式是普通JAR文件,但它也包括在其根目录中的模块info.class文件.上面的模块化JAR文件com.foo.bar module,例如,可能包含以下内容:

META-INF/
META-INF/MANIFEST.MF
module-info.class
com/foo/bar/alpha/AlphaFactory.class
com/foo/bar/alpha/Alpha.class
...
Run Code Online (Sandbox Code Playgroud)

模块化JAR文件可用作模块,在这种情况下,其module-info.class文件用于包含模块的声明.或者,它可以放在普通的类路径上,在这种情况下,它的module-info.class文件将被忽略.