如何用反射突破private方法的限制

414 阅读2分钟
原文链接: mp.weixin.qq.com

反射作为Java的一个提高点,经常作为面试的内容之一。今天介绍一下最基本的反射的使用。如何用反射来使用Class中的private方法。

private方法

我们知道被 private修饰的方法是无法被外部类调用的。但是有些时候当类所提供的方法不满足需求时,我们就得想办法来修改类的行为了。比如一些SDK里的方法,在被封装成jar/aar后我们不能再修改源码,此时只能用反射来做到。

万年Student

我们用一个已经用腻的类 Student来举例

class Student {    int age;    String name;    public Student(int age, String name) {      this.age = age;      this.name = name;    }    public String getName() {      return name;    }    private void getInfo() {      System.out.println("name: " + this.name + " age:" + this.age);    }}

反射之前的准备

Sutdent的 getInfo()方法我们特意改成private的,只留给外部类一个 getName()方法可以调用。当然实际项目中的场景会比这个复杂一些,我们只是用它来说明如何使用反射来调用 private方法。下面是我们的调用类

class StudentMain {    public static void main(String[] args) {      Student student = new Student(15, "Michael");      System.out.println("name: " + student.getName());    }}

well…运行之后输出下面的数据

name: Michael

反射它!

直接上代码

class StudentMain {    public static void main(String[] args) {      Student student = new Student(15, "Michael");      System.out.println("name: " + student.getName());      try {          Class class1 = Class.forName("Student");          Method method = class1.getDeclaredMethod("getInfo");          method.setAccessible(true);          method.invoke(student);      } catch (Exception exp) {          exp.printStackTrace();      }    }}

try里面这部分就是反射的具体代码了。用 getDeclaredMethod可以获取到所有的方法,class还有另一个方法 getMethod,这个只能获取到 public的方法。对于 private,不仅需要用 getDeclaredMethod来获取,还需要用 setAccessible true来压制对 private的检查。

最后输出结果

java StudentMainname: Michaelname: Michael age:15

总结

反射的作用又很多,上面只是举了个简单的例子如何通过反射来调用 private方法。以后我们会用几篇详细的文章来具体的分析反射,作为Java的一个重点知识点,了解反射不仅对面试有帮助,而且实际项目开发中很多地方也要用到反射。举个例子,对于Android的Toast,我们可以用反射来自定义它的样式和展示时间,让它可以摆脱原生的黑色半透明的UI,和显示比 LENGTH_LONG更长的时间。