1. 主页 > 大智慧

Java反射获取类所有方法的3种方式,附实例代码

你遇到过这种情况吗?新手如何快速涨粉般急切需要获取Java类里的方法,却对着反射API文档一脸懵?比如有个User类,里面有公共方法、私有方法甚至父类继承的方法——咱们怎么把它们"一网打尽"?今天咱们就掰开揉碎了说这事,手把手教你三种获取类方法的实用姿势。

先来个灵魂拷问:为什么要用反射获取方法?直接User.class.getMethods()不香吗?哎你别说,上周我就踩过这个坑。当时有个需求要获取所有方法包括私有方法,结果用getMethods()死活拿不到。后来才发现——原来这个API只能获取公共方法!

??方法一:getMethods()??
这个是最基础的入门姿势。就像这样:
Class<? > clazz = User.class;
Method[] methods = clazz.getMethods();
但注意了,这个方法会返回所有公共方法,包括继承来的。比如你的User类继承了BaseEntity,那父类的public方法也会出现在这里。

??方法二:getDeclaredMethods()??
这个才是真正的大杀器。来试试:
Method[] declaredMethods = clazz.getDeclaredMethods();
它能获取当前类声明的所有方法(包括private、protected),但不会包含继承的方法。不过有个坑要注意——获取私有方法后直接调用会抛异常,得先setAccessible(true)才行。

??方法三:混合双打??
有时候既要当前类的方法又要继承的,怎么办?咱们可以这样玩:

  1. 先获取父类
  2. 递归获取所有父类的方法
  3. 合并当前类的declaredMethods
    虽然麻烦,但确实能解决某些特殊需求。

现在咱们做个对比表格:
方法名 ? ? ? ? ? ? 包含私有 ? 包含继承 ? 包含父类
getMethods() ? ? ? ? 否 ? ? ? ? 是 ? ? ? ? 是
getDeclaredMethods() 是 ? ? ? ? 否 ? ? ? ? 否
混合方案 ? ? ? ? ? ? 是 ? ? ? ? 是 ? ? ? ? 是

可能有同学要问:获取方法的时候,参数类型怎么处理?比如重载方法。这里有个技巧,可以通过Class对象数组指定参数类型:
Method method = clazz.getDeclaredMethod("setName", String.class);
这样就能精确获取到特定方法了。

说到实际应用,上周我碰见个需求:要动态调用第三方jar包里的私有方法。这时候反射就派上大用场了。不过要提醒各位,虽然反射能突破封装,但滥用会导致性能问题和安全隐患。就像新手如何快速涨粉不能走歪门邪道,反射的使用也要遵循规范。

最后说个冷知识:JVM底层其实把方法访问权限检查给绕过去了。当咱们调用method.setAccessible(true)时,实际上是在告诉JVM:"哥们,我知道自己在干啥,放行吧!"不过这个操作会被SecurityManager拦截,生产环境要特别注意。

小编观点:反射就像把双刃剑,用好了能解决很多棘手问题,用不好就是给自己埋雷。新手建议从简单场景入手,比如单元测试中访问私有方法,等熟练了再玩高阶操作。记住——能不用反射尽量不用,实在绕不过去时,记得做好异常处理和权限控制。

本文由嘻道妙招独家原创,未经允许,严禁转载