getmethod用于获取当前类及父类/接口中所有public方法,支持继承但不支持private;getdeclaredmethod仅获取当前类声明的所有方法(含private),调用私有方法必须配合setaccessible(true)。

Java 反射机制可以在运行时动态获取类的方法并调用,无论方法是 public 还是 private。关键区别在于获取方法的方式和是否需要绕过访问控制检查。
调用公有方法(含继承的)
使用 getMethod() 获取公有方法,它会搜索当前类及其父类/接口中所有 public 的方法(包括继承来的),但不支持私有或受保护方法。
- 需传入方法名和参数类型的 Class 对象(如
String.class、int.class) - 目标对象可以是任意实例,包括
null(若为静态方法) - 无需调用
setAccessible(true)
示例:
String str = "hello";
Method method = String.class.getMethod("length"); // 无参 public 方法
int len = (int) method.invoke(str); // 输出:5
Method concat = String.class.getMethod("concat", String.class);
String result = (String) concat.invoke(str, " world"); // 输出:"hello world"
调用本类声明的私有方法
必须使用 getDeclaredMethod() —— 它只查当前类自己定义的方法(含 private/protected/public),不找继承的。这是调用私有方法的唯一正确入口。
- 获取后必须立即调用
method.setAccessible(true),否则 invoke 会抛IllegalAccessException - 参数类型要严格匹配,比如
private void doWork(int, String)就得写getDeclaredMethod("doWork", int.class, String.class) - 若方法无参,invoke 传
null或空数组new Object[0]
示例:
Test obj = new Test("test");
Method priv = Test.class.getDeclaredMethod("concatStr", String.class);
priv.setAccessible(true);
String res = (String) priv.invoke(obj, "123"); // 输出:"test123"
调用静态方法(公有或私有)
静态方法不需要实例对象,invoke 第一个参数传 null 即可。获取方式与普通方法一致:
- 公有静态方法 →
getMethod("methodName", ...) - 私有静态方法 →
getDeclaredMethod("methodName", ...)+setAccessible(true)
注意:即使方法是 static,只要它是 private,仍必须用 getDeclaredMethod 并设为可访问。
常见注意事项
反射调用私有成员属于打破封装的行为,实际使用中需留意:
- JDK 9+ 模块系统默认禁止跨模块访问,
setAccessible(true)在某些场景下会失效(如调用java.base中的私有 API) - 安全管理器(SecurityManager)启用时可能直接拒绝操作
- 性能低于直接调用,频繁使用会影响效率
- 编译期无法检查,出错在运行时,调试成本高
- 仅建议用于测试、框架开发、序列化工具等必要场景,避免出现在业务主流程中
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











