开放模块是Java中用open关键字声明的模块,允许其他模块在运行时通过反射访问其所有包;定义时在module-info.java中使用open module,无需逐个opens,但exports仍需显式声明。

什么是开放模块
开放模块(Open Module)是 Java 模块系统中一种特殊类型的模块,它在声明时使用 open 关键字修饰。它的核心作用是:允许其他模块在运行时通过反射访问该模块内所有被 opens 的包(即使未显式声明 opens,整个模块也会默认开放全部包)。这与普通模块形成对比——普通模块必须用 opens 显式指定哪些包可被反射访问。
如何定义开放模块
定义开放模块只需在 module-info.java 文件的模块声明前加上 open 关键字:
- 最简形式:
open module com.example.app { } - 带依赖和导出:
open module com.example.app { requires java.base; exports com.example.api; }
注意:一旦加了 open,该模块中所有包都自动对任意其他模块开放反射访问权限(包括未导出的包),无需再逐个写 opens 语句。但 exports 仍需显式声明,才能让其他模块直接 import 使用其 public 类型。
开放模块 vs 普通模块中的 opens
二者目标一致(支持反射),但粒度和适用场景不同:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 普通模块用
opens com.example.config;—— 只开放指定包,且仅限该包;适合精细控制 - 开放模块用
open module ... { ... }—— 整个模块所有包均开放反射;适合测试框架、Spring 等需要深度反射注入的场景 - 若同时存在
open module和opens子句,opens语句会被忽略(因为已全局开放)
典型使用场景
开放模块主要用在以下情况:
- 集成 Spring Framework(尤其老版本或非模块化 Spring Boot 应用),避免
IllegalAccessError或InaccessibleObjectException - 单元测试模块(如使用 JUnit 5 + Mockito),需反射访问私有字段或方法
- 动态代理、序列化框架(如 Jackson 在模块化环境下反序列化私有构造器)
例如,Spring 启动时常需添加:open module com.example.service { opens com.example.service.config to spring.core; },而更彻底的做法是直接定义为 open module com.example.service,省去逐包声明。

















