讲师中心 微信公众号
AI工具推荐 视频效率加速

如何解决Java反射访问非公开成员的警告_JDK 9+模块化权限开启

落萱姑娘_5170

落萱姑娘_5170

发布时间:2026-03-12 02:45:32

|

1115人浏览过

|

来源于php中文网

原创

JDK 9+ 模块系统严格限制反射访问,未导出/未开放的包或成员调用 setAccessible(true) 会触发警告(JDK 9–15)或直接抛 InaccessibleObjectException(JDK 16+),需通过 --add-opens 运行时参数显式授权,如 --add-opens java.base/java.util=ALL-UNNAMED。

如何解决java反射访问非公开成员的警告_jdk 9+模块化权限开启

为什么 setAccessible(true) 在 JDK 9+ 会触发警告甚至失败

不是代码写错了,是 JVM 真的在拦你——JDK 9 引入模块系统后,java.base 等核心模块默认禁止反射穿透非导出包(比如 sun.misc.Unsafe)或非公开成员。即使调用 setAccessible(true),也会收到 WARNING: Illegal reflective access 日志,且在 JDK 16+ 默认直接抛 InaccessibleObjectException。

根本原因不是反射本身被禁,而是模块间访问控制变严格了:一个模块没显式 opens 或 exports,你就不能通过反射碰它的类/字段/方法。

  • 常见错误现象:java.lang.reflect.InaccessibleObjectException: Unable to make field private java.util.ArrayList.elementData accessible
  • 典型场景:序列化框架(如 Kryo)、ORM(如 Hibernate 的字段注入)、测试工具(Mockito 字段 mock)在升级 JDK 后突然崩
  • 注意:--add-opens 是运行时参数,编译期完全不检查,所以编译通过、运行报错很常见

怎么用 --add-opens 精准放开模块权限

必须在 JVM 启动时加参数,粒度到「源模块→目标包」,不能只写模块名。格式是 --add-opens 源模块/包=目标模块,比如你要反射访问 java.util.ArrayList 的私有字段,得放开 java.base/java.util 包给你的模块(或 ALL-UNNAMED)。

  • 最常用写法(适用于大多数第三方库和测试):--add-opens java.base/java.util=ALL-UNNAMED
  • 如果明确知道自己的模块名(如 com.example.app),更安全:--add-opens java.base/java.util=com.example.app
  • 多个包要放开?重复写多条参数,不能合并:--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED
  • 别乱用 --add-modules ALL-SYSTEM,它不解决反射权限问题,纯属误导

IDE 和构建工具里怎么配才生效

很多人在代码里加了 --add-opens 却没效果,是因为只改了编译配置或 Maven 的 compilerArgs——那些参数只影响 javac,不影响 JVM 运行时。必须塞进「运行时 JVM 参数」里。

立即学习“Java免费学习笔记(深入)”;

  • IntelliJ IDEA:Run → Edit Configurations → VM options 输入框里粘贴,例如:--add-opens java.base/java.time=ALL-UNNAMED
  • Maven Surefire(跑测试):<jvmArgs>--add-opens java.base/java.lang=ALL-UNNAMED</jvmArgs> 放在 <configuration> 下
  • Gradle:test { jvmArgs = ['--add-opens', 'java.base/java.lang=ALL-UNNAMED'] }
  • Spring Boot 启动 jar:直接加在命令后面,java --add-opens ... -jar app.jar

替代方案:什么时候该放弃反射,改用其他方式

加 --add-opens 是最快解法,但长期看不健康——它把模块边界形同虚设,且 JDK 未来可能彻底移除该开关。真要稳定,优先考虑不碰私有成员。

  • 用标准 API 替代:比如想读 ArrayList.size,别反射字段,用 list.size();想清空,用 list.clear()
  • 找官方支持的扩展点:Hibernate 提供 @AccessType,Jackson 有 @JsonCreator + 全参构造器,比反射字段更可靠
  • 如果是单元测试需要 mock 私有方法:用 Mockito.mockStatic()(Mockito 4+)或 PowerMock(慎用,兼容性差),而不是自己写反射调用
  • 模块内访问?把相关类提到同一模块,并在 module-info.java 里用 opens 声明包:opens com.example.internal to com.example.test;

模块系统不是来添堵的,是逼你把依赖关系显式化。反射绕过封装容易,但哪天 ArrayList 内部字段重命名,或者模块策略收紧,所有 --add-opens 都得重新对一遍。

热门AI工具

更多
PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

10957

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

8082

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

7012

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

1184

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

968

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

1416

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2889

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

20171

2023.08.03

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

0

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn