我正在从What's New in Java9 中了解 Java 9 ,讨论中的热门话题之一是The Modular JDK。
JAR 文件是模块吗?
模块与 JAR 文件有何不同?
Module: A new language feature introduced in Java 9 (similar to class, interface, package, etc.) that consists of a collection of packages, similar to how a package consists of a collection of types.
JAR: An archive file format that bundles code and resources and which can be loaded by the JVM.
More specifically, a module is defined as follows:
In order to provide reliable configuration and strong encapsulation in a way that is both approachable to developers and supportable by existing tool chains we treat modules as a fundamental new kind of Java program component. A module is a named, self-describing collection of code and data. Its code is organized as a set of packages containing types, i.e., Java classes and interfaces; its data includes resources and other kinds of static information.
...
A module’s self-description is expressed in its module declaration, a new construct of the Java programming language.
...
A module declaration is compiled, by convention, into a file named
module-info.class
, placed similarly in the class-file output directory.
A module can be compiled into a Jar file, in which case the Jar file is labelled a modular Jar file:
Existing tools can already create, manipulate, and consume JAR files, so for ease of adoption and migration we define modular JAR files. A modular JAR file is like an ordinary JAR file in all possible ways, except that it also includes a
module-info.class
file in its root directory.
Some other differences between a module and a JAR:
Modules can require other modules in order to allow accessing dependent classes by the requiring module. A Jar has no such dependency concept.
A module can decide which classes and interfaces to export to other modules that require it. A Jar has no such encapsulation mechanism.
A module can be compiled into a modular Jar file, but some modules (e.g. JDK modules) are compiled into another format called JMOD.
The name of a JAR can be changed. As long as the JVM classloader finds the needed class on the classpath (which can be composed of a single JAR, multiple JARs, or a mix between directories or JARs), the name of the JAR file can be anything. However, the name of a module can be explicitly referenced in the declaration of other modules, and such the name defines it and cannot be changed freely.
严格来说,模块是一个运行时概念。正如其他人从模块系统的状态中引用的那样:
模块是一个命名的、自描述的代码和数据集合。它的代码被组织成一组包含类型的包,即Java 类和接口。它的数据包括资源和其他种类的静态信息。
这与JAR非常相似,但是...
这就留下了一个问题,模块从何而来?有多种方法,但对开发人员来说最突出的一种是模块化 JAR。模块化 JAR就像一个普通 JAR,但它包含一个模块描述符,一个module-info.class
从module-info.java
. 正是该文件定义了模块的名称、依赖项和 API。
所以 JAR 和模块之间有很强的联系:JAR 是模块系统从中创建模块的容器,并且(目前)每个 JAR 只能包含一个模块。值得注意的是,即使在 Java 9 上,JAR 也不必是模块化的——普通的 JAR 完全可以。
JAR 文件是模块吗?Module 与 JAR 文件有何不同?
不,Java Archive不是Module。
举个例子,虽然同一个包的类可以分布在 JAR中,但现在不能从多个模块中读取同一个包。
JAR是一种文件格式,可让您将多个文件捆绑到一个存档文件中。通常这包含与小程序和应用程序相关的类文件和辅助资源。
另一方面(我也试过在这里描述这个〜> java-module)
模块是一个命名的、自描述的代码和数据集合。它的代码被组织成一组包含类型的包,即Java 类和接口。它的数据包括资源和其他种类的静态信息。
这也包括在module-info.java
.
每个模块定义要么
模块工件,即包含已编译模块定义的模块化 JAR 文件或 JMOD 文件,或者
一个展开的模块目录,按照惯例,其名称是模块的名称,其内容是对应于包层次结构的“展开”目录树。
正如模块系统介绍的那样,模块化映像由模块而不是 JAR 文件组成。在模块化 WAR 文件方面,动态配置也可以预见模块化。
但是为了便于模块的采用,在 JDK9 中引入了一个模块化 JAR 文件,这样我们就可以说一个由module-info.java
这样的模块组成的模块
module com.foo.bar { }
和其他java类作为
com/foo/bar/alpha/AlphaFactory.java
com/foo/bar/alpha/Alpha.java
现有工具已经可以创建、操作和使用 JAR 文件。模块化 JAR文件在所有可能的方面都类似于普通的 JAR 文件,除了它还在其根目录中包含一个 module-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 ...
模块化 JAR 文件可以用作模块,在这种情况下,它的 module-info.class 文件被用来包含模块的声明。或者,它可以放在普通的类路径上,在这种情况下,它的 module-info.class 文件将被忽略。