Java9模块化是Java9版本中引入的一个重要特性,通过Java Platform Module System (JPMS)实现。这个特性允许开发者将大型应用程序拆分成相互独立的模块,每个模块包含一组相关的功能和资源。
关键概念与语法
下面是Java9模块化的一些关键概念和语法:
-
模块(Module):模块是一组相关的包的集合,它们被组织在一起以实现高内聚性和低耦合性。每个模块都有一个唯一的名称,通过module-info.java文件来声明模块的信息。
-
模块声明:在每个模块的根目录下创建module-info.java文件,使用module关键字声明模块,指定模块的名称、依赖关系和导出的包等信息。
-
模块路径:模块路径是用来指定模块的位置的路径。在编译和运行时,可以使用–module-path选项指定模块路径,告诉Java编译器和运行时在哪里查找模块。
-
模块间依赖:通过requires关键字声明模块之间的依赖关系,确保在编译和运行时正确加载依赖的模块。
-
导出包:使用exports关键字导出包,使得其他模块能够访问该包中的类。可以通过to关键字限制只有特定模块可以访问导出的包。
-
开放包:使用opens关键字开放包,允许其他模块通过反射访问该包中的类。
-
模块化编译和运行:使用javac编译器和java命令运行模块化的Java应用程序,需要在命令行中指定模块路径和要运行的模块。
模块化的优势:
- 更好的封装性:模块化强制隐藏内部实现细节,只暴露必要的API接口,这增强了封装性,降低了模块间的耦合度。
- 可维护性:通过将应用程序拆分成多个模块,每个模块都可以独立地进行开发和测试,从而提高了可维护性。
- 性能优化:模块系统可以更有效地加载和管理类,从而可能提高应用程序的性能。
模块化的使用
以下是一个简单的Java9模块化的使用例子:
假设我们有一个Java项目,其中包含两个模块:main(主模块)和user(用户模块)。主模块需要使用用户模块中的某个类(比如User类)。
创建目录结构
首先,我们需要创建项目的目录结构。在这个例子中,我们将有两个模块,所以目录结构如下所示:
java9-module-demo/
├── main
│ ├── module-info.java
│ └── src
│ └── com
│ └── morris
│ └── main
│ └── Main.java
└── user├── module-info.java└── src└── com└── morris├── other│ └── HiddenClass.java└── user└── User.java
编写模块描述符(module-info.java)
在每个模块的根目录下,我们需要创建一个module-info.java文件来定义模块。
对于main模块(主模块):
// main/module-info.java
module main {requires user; // 声明对用户模块的依赖
}
对于user模块(用户模块):
module user {exports com.morris.user; // 声明导出com.morris.user包,以便其他模块可以访问它// 注意:我们没有导出HiddenClass类所在的包,所以其他模块不能访问它
}
编写Java类
在main模块的Main.java文件中:
// main/src/com/morris/main/Main.java
package com.morris.main;import com.morris.user.User;public class Main {public static void main(String[] args) {User user = new User(); // 创建User类的实例System.out.println("Hello, " + user.getName()); // 假设User类有一个getName()方法}}
在user模块的User.java文件中:
// user/src/com/morris/user/User.java
package com.morris.user;public class User {private static final String NAME = "Morris";public String getName() {return NAME;}
}
注意:HiddenClass.java在这个例子中没有被使用,并且由于它所在的包没有被导出,所以com.morris.main模块不能访问它。
如果在com.morris.main模块访问HiddenClass,编译时会抛出以下的错误:
main/src/com/morris/main/Main.java:3: error: package com.morris.other is not visible
import com.morris.other.HiddenClass;^(package com.morris.other is declared in module user, which does not export it)
1 error
编译
先编译user模块:
$ javac -d out/user user/module-info.java user/src/com/morris/user/Us
er.java user/src/com/morris/other/HiddenClass.java
后编译main模块:
$ javac -d out/main --module-path out/user main/module-info.java main/src/com/morris/main/Main.java
编译后目录结构如下:
java9-module-demo/
├── main
│ ├── module-info.java
│ └── src
│ └── com
│ └── morris
│ └── main
│ └── Main.java
├── out
│ ├── main
│ │ ├── com
│ │ │ └── morris
│ │ │ └── main
│ │ │ └── Main.class
│ │ └── module-info.class
│ └── user
│ ├── com
│ │ └── morris
│ │ ├── other
│ │ │ └── HiddenClass.class
│ │ └── user
│ │ └── User.class
│ └── module-info.class
└── user├── module-info.java└── src└── com└── morris├── other│ └── HiddenClass.java└── user└── User.java
运行
通过--module-path
选项指定模块路径,告诉Java运行时在哪里查找模块:
$ java --module-path out --module main/com.morris.main.Main
Hello, Morris