Java可通过反射调用私有方法,核心是getDeclaredMethod()获取再调用setAccessible(true)跳过访问检查,但受模块系统、SecurityManager及Android运行时限制,且应避免在生产环境滥用。

Java 可以通过反射调用私有方法,核心是用 setAccessible(true) 跳过 Java 的访问控制检查。但要注意:这仅在运行时生效,不改变类定义;且从 Java 9+ 开始受模块系统限制,某些 JDK 内部类可能无法绕过。
获取私有方法对象
使用 getDeclaredMethod()(不是 getMethod()),它能查到本类声明的所有方法(含 private),而 getMethod() 只返回 public 且可继承的方法。
例如:
```javaClass> clazz = MyClass.class;
Method privateMethod = clazz.getDeclaredMethod("doSomething", String.class, int.class);
```
取消访问限制
必须显式调用 setAccessible(true),否则执行 invoke() 时会抛 IllegalAccessException。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
立即学习“Java免费学习笔记(深入)”;
- 该操作对当前
Method对象生效,不影响其他反射对象 - 若在安全管理器(SecurityManager)启用的环境中,可能抛
SecurityException - Java 12+ 对某些关键内部 API 默认禁止,需加 JVM 参数如
--add-opens java.base/java.lang=ALL-UNNAMED
调用私有方法
调用方式与公有方法一致,传入目标实例(静态方法传 null)和参数数组:
privateMethod.setAccessible(true);
Object result = privateMethod.invoke(new MyClass(), "test", 42);
```
注意:
- 若方法是 static,第一个参数传
null - 参数类型必须严格匹配(或可自动装箱/拆箱),否则抛
IllegalArgumentException - 若私有方法抛出受检异常,它会被包装为
InvocationTargetException,需用e.getCause()获取原始异常
实用建议
- 尽量避免在生产代码中反射调用私有方法——破坏封装,易受重构影响
- 单元测试中可谨慎使用(如 Mockito 也依赖类似机制),但优先考虑通过公有接口验证行为
- Android 上 Dalvik/ART 对反射有限制,部分私有 API 在高版本不可用,需适配
- 如需频繁调用,可缓存
Method对象并复用setAccessible(true),提升性能

















