Java反射可通过setAccessible(true)调用私有方法,需先获取Class对象(类名.class、对象.getClass()、Class.forName),再用getDeclaredMethod获取并调用;但受SecurityManager、模块系统限制,且存在性能与维护性问题。

Java 反射可以动态获取类对象并调用私有方法,核心是绕过访问控制检查(setAccessible(true)),但需注意安全限制和运行时异常处理。
获取 Class 对象的几种方式
要操作类,必须先拿到 Class 实例:
-
类名.class:最常用,编译期已知类,如
String.class -
对象.getClass():适用于已有实例,如
"hello".getClass() -
Class.forName("全限定类名"):动态加载,需捕获
ClassNotFoundException,如Class.forName("java.util.ArrayList")
获取并调用私有方法
通过 getDeclaredMethod() 获取私有方法(getMethod() 只查 public 方法),再用 setAccessible(true) 关闭 Java 访问检查:
- 调用前必须传入目标对象(静态方法传
null) - 参数类型需严格匹配,基本类型用包装类或对应 Class 常量(如
int.class) - 调用时传参顺序、类型必须与方法签名一致,否则抛
IllegalArgumentException
示例代码片段:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
立即学习“Java免费学习笔记(深入)”;
Class<?> clazz = Class.forName("com.example.MyClass");
Object instance = clazz.getDeclaredConstructor().newInstance();
Method privateMethod = clazz.getDeclaredMethod("doSomething", String.class);
privateMethod.setAccessible(true); // 关键:跳过权限检查
Object result = privateMethod.invoke(instance, "test");
常见问题与注意事项
反射调用私有方法不是“万能钥匙”,实际使用中要注意:
-
SecurityManager:若 JVM 启用了安全管理器且未授权,
setAccessible(true)会抛SecurityException -
模块系统(Java 9+):在强封装模块中(如
java.base),默认禁止反射访问内部 API,需启动参数--add-opens - 性能开销:反射比直接调用慢,且无法被 JIT 充分优化,避免高频场景使用
- 可维护性:私有方法属于实现细节,可能随版本变更,反射调用易导致运行时崩溃
调用私有构造器或字段同理
逻辑一致:用 getDeclaredConstructor() / getDeclaredField() 替代 getDeclaredMethod(),同样需 setAccessible(true) 才能操作。
例如获取私有字段值:
Field field = clazz.getDeclaredField("secretValue");
field.setAccessible(true);
Object value = field.get(instance);

















