Java9模块依赖全解析
立即解锁
发布时间: 2025-08-18 02:22:42 阅读量: 1 订阅数: 8 

### Java 9 模块依赖全解析
#### 1. 深度反射访问与类型可访问性
在 Java 开发中,有时会遇到模块需要对另一个未开放任何包且无法修改其声明的模块进行深度反射访问的情况。这时可以使用 `--add-opens` 选项来实现。
在 JDK 9 之前,类型有四种可访问性:
- `public`
- `protected`
- `<package>`
- `private`
在 JDK 8 中,`public` 类型意味着它可以被程序的所有部分访问。但在 JDK 9 中,情况发生了变化。在模块中定义的 `public` 类型可能属于以下三类之一:
- **仅在定义模块内公开**:如果一个类型在模块中被定义为 `public`,但该模块没有导出包含该类型的包,那么该类型仅在模块内公开,其他模块无法访问。
- **仅对特定模块公开**:如果一个类型在模块中被定义为 `public`,且模块使用限定的 `exports` 语句导出包含该类型的包,那么该类型仅对限定导出语句 `to` 子句中指定的模块可访问。
- **对所有模块公开**:如果一个类型在模块中被定义为 `public`,且模块使用非限定的 `exports` 语句导出包含该类型的包,那么该类型对读取该模块的所有模块公开。
#### 2. 跨模块拆分包的问题
跨模块拆分包是不允许的,即同一个包不能在多个模块中定义。如果同一个包中的类型存在于多个模块中,这些模块应该合并为一个模块,或者需要重命名这些包。有时,这些模块可以成功编译,但在运行时会出错;有时则会在编译时出错。
例如,有如下代码:
```java
// Test.java
package java.util;
public class Test {
}
```
如果在 JDK 9 中作为模块的一部分或单独编译这个 `Test` 类,会收到如下错误:
```
error: package exists in another module: java.base
package java.util;
^
1 error
```
这表明 `java.util` 包在当前模块和 `java.base` 模块中都对当前模块可读,必须将该类的包更改为在任何可观察模块中都不存在的包。
#### 3. 模块声明的限制
模块声明有以下几个限制,如果违反这些限制,会在编译时或启动时出错:
- **无循环依赖**:模块图不能包含循环依赖,即两个模块不能相互读取。如果存在这种情况,它们应该合并为一个模块。不过,在运行时可以通过编程方式添加可读性边或使用命令行选项来实现循环依赖。
- **不支持模块版本**:模块声明不支持模块版本,需要使用 `jar` 工具或其他工具(如 `javac`)将模块版本作为类文件属性添加。
- **无子模块概念**:模块系统没有子模块的概念,例如 `com.jdojo.person` 和 `com.jdojo.person.client` 是两个独立的模块,后者不是前者的子模块。
#### 4. 模块类型概述
Java 已经存在了 20 多年,新旧应用程序都会继续使用未模块化或永远不会模块化的库。为了实现向后兼容,JDK 9 定义了四种类型的模块:
- 正常模块
- 开放模块
- 自动模块
- 未命名模块
实际上,有六个术语描述了六种不同类型的模块,对于 JDK 9 的初学者来说,这些术语可能会造成混淆。其他两种类型的模块用于表示这四种类型模块的更广泛类别。模块类型的关系可以用以下 mermaid 流程图表示:
```mermaid
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(Module):::process --> B(Named Module):::process
A --> C(Unnamed Module):::process
B --> D(Normal Module):::process
B --> E(Open Module):::process
B --> F(Automatic Module):::process
B --> G(Explicit Module):::process
```
#### 5. 正常模块
使用模块声明显式声明且不使用 `open` 修饰符的模块总是有一个名称,称为正常模块,简称为模块。默认情况下,正常模块中的所有类型都是封装的。例如:
```java
module a.normal.module {
// Module statements go here
}
```
#### 6. 开放模块
如果模块声明中包含 `open` 修饰符,则该模块称为开放模块。例如:
```java
open module a.open.module {
```
0
0
复制全文
相关推荐










