核心是靠模块边界而非类访问修饰符;需在module-info.java中严格声明exports仅限api包、opens必须限定目标模块、禁用--add-opens等宽松启动参数,确保未导出包无法编译引用,未开放包无法反射访问。

核心是靠 模块边界 而不是类访问修饰符。private 或 package-private 在模块化环境下已不够用——只要类路径混乱或启动参数宽松,这些限制就可能被绕过。真正起作用的是 module-info.java 中对包的显式导出与开放策略。
只导出真正需要暴露的 API 包
未被 exports 的包,其他模块连编译都通不过,更别说运行时加载了。
- 明确列出对外接口所在的包,例如:
exports com.example.api; - 坚决不导出含实现逻辑、配置、内部工具的包,比如
com.example.internal、com.example.config - 避免导出整个顶层包(如
exports com.example;),否则会把子包全放开
禁止无约束反射访问,慎用 opens
opens 是唯一允许反射穿透模块边界的合法通道,但它必须指定目标模块,不能放任不管。
- 需要反射支持时(如 JSON 序列化),写法必须带目标:
opens com.example.model to com.fasterxml.jackson.databind; - 禁用无目标写法:
opens com.example.model;或通配写法:opens com.example.*; - 不依赖反射的模块,就完全不写
opens,让强封装生效
切断隐式依赖和非法启动选项
模块描述只是契约,JVM 执行时若被降级,边界就形同虚设。
- 启动参数中禁用宽松模式:
--illegal-access=deny(Java 16+ 默认开启,旧版本务必显式加) - 不使用
--add-opens java.base/java.lang=ALL-UNNAMED这类全局放行指令 - 检查第三方库是否真的在
requires列表里——没声明依赖的模块,连反射入口都进不来
资源与非类文件也要按模块路径管理
虽然模块系统没有 exports resources 语法,但资源访问同样受模块边界约束。
- 配置文件等资源若需跨模块读取,应放在已导出的包内(如
src/main/java/com/example/api/config.json),再通过Class.getResource()访问 - 放在
src/main/resources/下的资源属于模块根目录,必须用Module.getResourceAsStream("xxx"),不能依赖上下文类加载器 - 第三方模块未导出含资源的包,即使文件物理存在,也无法被你模块直接读取
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











