对程序员来说,放假只是换了一个写代码的地方!
看一下Java(Android)里面的反射怎么用:
一、先来定义两个类(一个父类,一个子类):
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);}}


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);}@Overridevoid getPhone() {System.out.println("I am sun , My age is " + age + "___" + var2);}@Overridepublic void update(Observable o, Object arg) {}}


以上两个类只是为了测试,不用关心具体实现代码,只要知道有private变量和方法,protected变量和方法,public变量和方法。重点在下面:

二、利用反射,调用上面的类:
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");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里面的具体事例:

/** * 获得包的大小 *  * @param pkgName * @throws Exception */public void queryPacakgeSize(String pkgName) throws Exception {if (pkgName != null) {// 使用放射机制得到PackageManager类的隐藏函数getPackageSizeInfoPackageManager 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;// 抛出异常}}}

关于反射的使用,基本就这些了,代码注释已经很详细了,就不需要多余的说明了,想了解反射的原理,建议大家看源码!
参考:http://www.cnblogs.com/crazypebble/archive/2011/04/13/2014582.html

更多相关文章

  1. BiliBili-IJKPlayer播放器源码分析(一)
  2. Android中工作线程与主线程同步方式
  3. android中调用系统功能 来显示本地相册图片 拍照 视频 音频功能
  4. Android事件分发和View绘制流程分析(三)
  5. Android手势检测简介
  6. Android调用getSimSerialNumber获取iccid不完整
  7. Android(安卓)Camera调用流程
  8. Android(安卓)无线启动过程分析 无线启动过程分析
  9. android中webView JS调用Android的方法、webView的下拉刷新(Swipe

随机推荐

  1. 解决WebView加载URL跳转到系统浏览器的问
  2. android kernel启动学习笔记
  3. 风投称Android将像Windows一样主宰移动市
  4. Android签名漏洞分析
  5. Android自定义权限的使用
  6. Android Schema的妙用
  7. ANDROID – TOOLBAR STEP BY STEP
  8. Android聊天室(服务器)
  9. android:viewpager实现图片循环滑动+索引
  10. Android Studio App设置线性布局LinerLay