module-info.java是java 9模块系统(jpms)的强制入口文件,必须置于模块源码根目录(如src/main/java/),命名严格为module-info.java;需用module声明名称,requires显式声明依赖(含transitive/static),exports控制包可见性,opens限定反射访问。

模块描述符 module-info.java 是 Java 9 模块系统(JPMS)的配置核心,必须放在模块根目录下,且只能有一个。它不是普通类,不属任何包,编译后生成独立的 module-info.class。写错语法或结构会导致编译失败、依赖无法解析、包不可见等问题。
基本结构与命名规则
一个合法的 module-info.java 至少包含 module 关键字和模块名:
- 模块名必须是有效的 Java 标识符,推荐使用反向域名风格(如
com.example.user),不能含连字符或数字开头 - 模块名与所在目录名**无需一致**,但强烈建议保持一致,避免路径管理混乱
- 文件必须命名为
module-info.java,大小写敏感,不能是ModuleInfo.java或module_info.java - 文件必须位于模块源码根目录(即
src同级或直接作为模块根),例如:user/module-info.java,而非user/src/module-info.java
声明依赖:requires 的用法要点
用 requires 显式声明所依赖的其他模块,这是编译期强约束:
-
requires java.sql;—— 依赖 JDK 系统模块(无需路径,自动可用) -
requires com.fasterxml.jackson.databind;—— 依赖第三方命名模块(需确保该 JAR 在模块路径中) -
requires static org.junit.jupiter.api;—— 声明可选依赖(仅编译/测试时需要,运行时不要求) -
requires transitive javafx.controls;—— 表示该依赖会“传递”给当前模块的使用者(别人requires你时,也自动获得 javafx.controls) - 不能
requires未导出包所在的模块——即使写了,也无法访问其内部类;必须配合对方模块的exports才生效
控制对外可见性:exports 与 opens
默认所有包都私有,外部模块无法访问,必须显式开放:
-
exports com.example.service;—— 允许其他模块正常 import 和使用该包下的 public 类 -
exports com.example.service to com.example.client;—— 限制只对指定模块开放(需对方模块名已知) -
opens com.example.config;—— 允许反射访问(如 Spring、Hibernate 运行时注入),但不允日常 import -
opens com.example.config to com.example.data;—— 限定反射权限范围,提升安全性 - 注意:
opens不等于exports;一个包可以只开放反射而不导出,反之亦然
常见错误与避坑提示
这些写法看似合理,实际会触发编译错误或运行时异常:
- 在
module-info.java中写import语句——非法,该文件不支持 import - 把
module-info.java放进某个包目录(如src/com/example/mymodule/)——找不到模块描述符,视为无模块 - 依赖了模块却没
exports对应包,然后在其他模块里 import 该包类——编译报错 “package is not visible” - 误以为
public class就能被外部访问——模块内封装优先于类访问修饰符,exports缺失时,public 类也对外不可见 - 混淆
requires和requires static:后者若在运行时缺失,不会导致NoClassDefFoundError;前者缺失则启动失败
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











