对程序员来说,放假只是换了一个写代码的地方!
看一下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);
}
}
<pre name="code" class="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变量和方法。重点在下面:
二、利用反射,调用上面的类:
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类的隐藏函数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;// 抛出异常
}
}
}
关于反射的使用,基本就这些了,代码注释已经很详细了,就不需要多余的说明了,想了解反射的原理,建议大家看源码!
http://www.cnblogs.com/crazypebble/archive/2011/04/13/2014582.html