首页 > 系统 > Android > 正文

Android 反射机制

2019-11-06 10:02:04
字体:
来源:转载
供稿:网友
参考博客:
http://www.cnblogs.com/crazypebble/archive/2011/04/13/2014582.htmlhttp://gqdy365.iteye.com/blog/2124969?utm_source=tuicool
http://blog.csdn.net/yq6073025/article/details/52782257

反射的作用

可以利用反射机制在java程序中,动态的去调用一些PRotected甚至是private的方法或类,然后可以在很大程度上满足我们的一些比较特殊需求。

实现反射的方法

先创建一个对象实例

方法1:

Class<?> cls=Class.forName(包名); 

Person p=(Person)cls.newInstance();

p.setAge(20);

方法2:

Person p = new Person();Class<?> cls=p.getClass();Person p2=(Person)cls.newInstance();

p.setAge(20);

方法3:

Class<?> cls=Person.Class();

Person p=(Person)cls.newInstance();//强制转换

p.setAge(20);

那么知道了反射机制如何生成类对象,之后就要开始调用类的方法了

Class<?>cls=Class.forName(包名); cls对象 可调用方法如下

方法关键字含义
getDeclareMethods()获取所有的方法
getReturnType()获取方法的返回值类型
getParameterTypes()获取方法的传入参数类型
getDeclareMethod("方法名,参数类型.class,....")获得特定的方法
 -
构造方法关键字含义
getDeclaredConstructors()获取所有的构造方法
getDeclaredConstructors(参数类型.class,....)获取特定的构造方法
 -
成员变量含义
getDeclaredFields获取所有成员变量
getDeclaredField(参数类型.class,....)获取特定的成员变量
 -
父类和父接口含义
getSuperclass()获取某类的父类
getInterfaces()获取某类实现的接口

举个例子例子参考博客:Android反射机制实例(因为懒,直接复制过来了。—  —)一、先来定义两个类(一个父类,一个子类): Java代码  收藏代码package com.zwq.test;    public abstract class Person {        String name = "";      private int age = 0;      public int fPubVar = 0;        abstract void getPhone();        public Person() {          System.out.println("I am Farther");      }        int myAge() {          return 50;      }        String myName() {          return "Father";      }        public void callSun() {          getPhone();          priMethod(25);      }        private void priMethod(Integer a) {          age = a;          System.out.println("I am priMethod , Dont call me! age " + age);      }        /**      * @hide      */      public void hideMethod(String name) {          System.out.println("I am hideMethod , Dont call me! name:" + name                  + "   age:" + age);      }  }  Java代码  收藏代码package com.zwq.test;    import java.util.Observable;  import java.util.Observer;    public class Man extends Person implements Observer {        private int age = 0;      private String var1 = "I am var1";      public int var2 = 20;        public Man() {          System.out.println("I am Man" + var1);          age = 20;      }        public int myAge() {          return 28;      }        public String myName() {          return "Jerome";      }            private void getName(){          System.out.println("I am Jerome");      }            /**      *@hide       */      private void getAge(){          System.out.println("I am "+age);      }        @Override      void getPhone() {          System.out.println("I am sun , My age is " + age + "___" + var2);      }        @Override      public void update(Observable o, Object arg) {        }  }  以上两个类只是为了测试,不用关心具体实现代码,只要知道有private变量和方法,protected变量和方法,public变量和方法。重点在下面: 二、利用反射,调用上面的类: Java代码  收藏代码package com. zwq.test;    import java.lang.reflect.Field;  import java.lang.reflect.Method;    public class Main {      public static void main(String[] args) {          getInfo();          callSpuerMethod();          callCurrentMethod();          callOtherMethod();      }        static void getInfo() {          Man r = new Man();          Class<?> temp = r.getClass();          try {              System.out.println("反射类中所有公有的属性");              Field[] fb = temp.getFields();              for (int j = 0; j < fb.length; j++) {                  Class<?> cl = fb[j].getType();                  System.out.println("fb:" + cl + "___" + fb[j].getName());              }              System.out.println("反射类中所有的属性");              Field[] fa = temp.getDeclaredFields();              for (int j = 0; j < fa.length; j++) {                  Class<?> cl = fa[j].getType();                  System.out.println("fa:" + cl + "____" + fa[j].getName());              }                System.out.println("反射类中所有的方法");              Method[] fm = temp.getMethods();              for (int i = 0; i < fm.length; i++) {                  System.out.println("fm:" + fm[i].getName() + "____"                          + fm[i].getReturnType().getName());              }                System.out.println("反射类中所有的接口");              Class<?>[] fi = temp.getInterfaces();              for (int i = 0; i < fi.length; i++) {                  System.out.println("fi:" + fi[i].getName());              }                System.out.println("反射类中私有属性的值");              Field f = temp.getDeclaredField("var1");  //var1属性名            f.setaccessible(true);              String i = (String) f.get(r);              System.out.println(i);          } catch (Exception e) {              e.printStackTrace();          }      }        /**      * 修复父类变量,调用父类方法      */      static void callSpuerMethod() {          Man r = new Man();          try {              // 修改私有变量;              Field f = r.getClass().getSuperclass().getDeclaredField("age");              f.setAccessible(true);              f.set(r, 20);                // 调用私有方法,必须要用getDeclaredMethod,而不能用getMethod;              Method mp = r.getClass().getSuperclass()                      .getDeclaredMethod("priMethod", Integer.class);              mp.setAccessible(true);              mp.invoke(r, 18);                // 调用隐藏方法              Method m = r.getClass().getSuperclass()                      .getMethod("hideMethod", String.class);              m.setAccessible(true);              m.invoke(r, "Jerome");          } catch (Exception e) {              e.printStackTrace();          }      }        /**      * 修复子类变量,调用子类方法      */      static void callCurrentMethod() {          Man r = new Man();          try {              // 修改私有变量;              Field f = r.getClass().getDeclaredField("age");              f.setAccessible(true);              f.set(r, 20);                // 调用私有方法,必须要用getDeclaredMethod,而不能用getMethod;              Method mp = r.getClass().getDeclaredMethod("getName");              mp.setAccessible(true);              mp.invoke(r);                // 调用隐藏私有方法              Method m = r.getClass().getDeclaredMethod("getAge");              m.setAccessible(true);              m.invoke(r);          } catch (Exception e) {              e.printStackTrace();          }      }        /**      * 用Class.forName加载类及实例化      */      static void callOtherMethod() {          try {              // Class.forName(xxx.xx.xx) 返回的是一个类, .newInstance() 后才创建一个对象              // Class.forName(xxx.xx.xx) 的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段              Class<?> cl = Class.forName("com.zwq.test.Man");              Object r = cl.newInstance();                // 修改私有变量;              Field f = cl.getDeclaredField("age");              f.setAccessible(true);              f.set(r, 20);                // 调用私有方法,必须要用getDeclaredMethod,而不能用getMethod;              Method mp = cl.getDeclaredMethod("getName");              mp.setAccessible(true);              mp.invoke(r);                // 调用隐藏私有方法              Method m = cl.getDeclaredMethod("getAge");              m.setAccessible(true);              m.invoke(r);          } catch (Exception e) {              e.printStackTrace();          }      }  }  三、最后贴一个Android里面的具体事例: Java代码  收藏代码/**      * 获得包的大小      *       * @param pkgName      * @throws Exception      */      public void queryPacakgeSize(String pkgName) throws Exception {          if (pkgName != null) {              // 使用放射机制得到PackageManager类的隐藏函数getPackageSizeInfo              PackageManager pm = getPackageManager(); // 得到pm对象              try {                  // 通过反射机制获得该隐藏函数                  Method getPackageSizeInfo = pm.getClass().getDeclaredMethod(                          "getPackageSizeInfo", String.class,                          ipackageStatsObserver.class);                  // 调用该函数,并且给其分配参数 ,待调用流程完成后会回调PkgSizeObserver类的函数                  getPackageSizeInfo.invoke(pm, pkgName, new PkgSizeObserver());                  // 停止主线程让PackageStats对象获得数据                  Thread.sleep(8);              } catch (Exception ex) {                  // Log.e("TAG", "NoSuchMethodException") ;                  ex.printStackTrace();                  throw ex;// 抛出异常              }          }      }  综上:

反射机制通过void setAccessible(boolean flag)方法可以得到一个类的private或者protected的方法和属性,使用这些private或者protected的方法和属性。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表