平时看源码经常会遇到反射的代码,这里记录下反射的用法,方便查阅。
首先在java中测试,创建父类Persion:
package com.invok;
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);
}
}
子类Man:
package com.invok;
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) {
}
}
获取属性和方法测试如下:
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("getFields:" + 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("getDeclaredFields:" + cl + "____" + fa[j].getName());
}
System.out.println("获取反射类中所有的方法");
Method[] fm = temp.getMethods();
for (int i = 0; i < fm.length; i++) {
System.out.println("getMethods:" + 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("getInterfaces:" + 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();
}
}
打印结果:
I am Farther
I am ManI am var1
获取反射类中所有公有的属性
getFields:int___var2
getFields:int___fPubVar
获取反射类中所有的属性
getDeclaredFields:int____age
getDeclaredFields:class java.lang.String____var1
getDeclaredFields:int____var2
获取反射类中所有的方法
getMethods:myAge____int
getMethods:myName____java.lang.String
getMethods:update____void
getMethods:hideMethod____void
getMethods:callSun____void
getMethods:wait____void
getMethods:wait____void
getMethods:wait____void
getMethods:equals____boolean
getMethods:toString____java.lang.String
getMethods:hashCode____int
getMethods:getClass____java.lang.Class
getMethods:notify____void
getMethods:notifyAll____void
获取反射类中所有的接口
getInterfaces:java.util.Observer
获取反射类中私有属性的值
I am var1
下面测试父类变量和父类方法:
/**
* 修复父类变量,调用父类方法
*/
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();
}
}
打印结果:
I am Farther
I am ManI am var1
I am priMethod , Dont call me! age 18
I am hideMethod , Dont call me! name:Jerome age:18
下面测试子类变量和方法:
/**
* 修复子类变量,调用子类方法
*/
static void callCurrentMethod() {
Man r = new Man();
try {
// 修改私有变量;
Field f = r.getClass().getDeclaredField("age");
f.setAccessible(true);
f.set(r, 21);
// 调用私有方法,必须要用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();
}
}
打印结果:
I am Farther
I am ManI am var1
I am Jerome
I am 21
/**
* 用Class.forName加载类及实例化
*/
static void callOtherMethod() {
try {
// Class.forName(xxx.xx.xx) 返回的是一个类, .newInstance() 后才创建一个对象
// Class.forName(xxx.xx.xx) 的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段
Class<?> cl = Class.forName("com.invok.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();
}
}
打印结果:
I am Farther
I am ManI am var1
I am Jerome
I am 20
下面看下android上的用法:
private void invorkTest() {
TelephonyManager mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
try {
Method method = mTelephonyManager.getClass().getDeclaredMethod("hasIccCard", int.class);
boolean hasIccCard = (Boolean)method.invoke(mTelephonyManager, 0);
Log.d("test", "hasIccCard = " + hasIccCard);
Method method1 = mTelephonyManager.getClass().getDeclaredMethod("getSimState", int.class);
int simState = (Integer)method1.invoke(mTelephonyManager, 0);
Log.d("test", "simState = " + simState);
Method method2 = mTelephonyManager.getClass().getDeclaredMethod("getImei", int.class);
String imei = (String)method2.invoke(mTelephonyManager, 0);
Log.d("test", "imei = " + imei);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
上面通过反射获取手机是否有SIM卡,和获取SIM卡状态,和手机IMEI。