1. 简介
Java 9 中的模块化系统是其最重要的新功能之一。在 Java 9 之前,Java 应用程序使用的是类路径来查找并加载类。类路径由一系列 JAR
文件组成,这些文件中包含了应用程序的所有依赖项,包括应用程序本身。这种类路径方式有助于简化应用程序的构建和部署,但也有一些缺点。在大型和复杂的应用程序中,类路径的管理可能会变得非常困难,导致应用程序的可维护性变差。因此,Java 9 引入了一个全新的模块化系统,通过将应用程序与依赖项组织成独立的模块,来解决这个问题。
2. 模块化
2.1 模块的定义
在 Java 9 中,模块是一组相关的包和资源,这些包和资源被组织成一个单独的单元,以便与其他单元进行交互。每个模块都定义了它所暴露的 API
(公共接口)和依赖项。模块使用 module-info.java
文件来定义这些信息。模块文件的基本结构如下:
module <module_name> {
// 导出的包
exports <package_name>;
// 导出和开放的包
exports <package_name> to <module_name>;
opens <package_name>;
// 使用的模块
requires <module_name>;
}
其中:
每个模块必须有一个唯一的名称,由一个 module_name
标识符表示
exports
关键字用于将一个包(由 package_name
标识符表示)作为该模块的 API
暴露出去,使其可以被其他模块访问。
opens
关键字用于将一个包作为开放包来暴露出去,允许其他模块使用反射访问该包内的类。
requires
关键字用于指定模块所依赖的其他模块。
exports <package_name> to <module_name>;
用于导出指定的包到另一个模块中,使该模块可以访问这些被导出的包,以此构成一种权限管理机制。
2.2 模块化对于 Java 应用程序的影响
Java 应用程序通过模块化系统可以实现更好的管理和控制程序依赖关系,从而提高了应用程序的可维护性和安全性。它允许应用程序在没有完整 JDK
安装的情况下运行,从而提高了应用程序的可移植性。
由于一个模块仅包含其公共 API
和依赖项,因此可以减少类路径中的 JAR
文件数量,从而降低了类路径的管理复杂度。由于在类路径中某些类可能被错误地加载,因此模块化系统可以帮助应用程序更好地控制类的可见性,从而提高了应用程序的安全性。
3. export 子句的作用
在 module-info.java
文件中,export
关键字用于指定该模块中哪些包对外可见,从而暴露接口,供其他模块使用。
我们来看一个例子,一个模块名为 com.example.myapp
,包含以下模块文件:
module com.example.myapp {
requires org.example.library;
exports com.example.myapp.service;
}
这里的 exports
语句指定了模块 com.example.myapp
中的 com.example.myapp.service
包可以被其他模块所使用。其他模块需要使用这个包中的类,只需要在 module-info.java
文件中添加一个 requires
语句,并在代码中导入该包即可:
module com.example.appclient {
requires com.example.myapp;
}
然后在代码中:
import com.example.myapp.service.MyService;
public class MyAppClient {
public static void main(String[] args) {
MyService service = new MyService();
service.doSomething();
}
}
在这个例子中,模块 com.example.myapp
导出了 com.example.myapp.service
包,以便其他模块可以随意使用其中的公共接口。
4. 总结
Java 9 引入了一套全新的模块化系统,使得 Java 应用程序可以以更好的方式管理依赖项,提高应用程序的可维护性和安全性,并提高了应用程序的可移植性。在模块中,export
子句的作用是指定该模块中哪些包可以被其他模块所使用,从而帮助开发者限制模块的可见性,提高应用程序的安全性和可维护性。