初级:
当我们一开始使用反射的时候,首先理解的是,他可以拦截一个方法,并执行其方法。
com.ml.maskpro.ui.MainActivity中包含如下方法:
public String getName(String name) {
return name + "的歌迷";
}
private String getAge(int age) {
return "歌迷的年龄"+age;
}
然后我们拦截这两个方法如下:
public static void inject3(Activity activity) {
try {
//获取字节码
// Class stuClass = Class.forName("com.ml.maskpro.ui.MainActivity");
Class stuClass = activity.getClass();
//获取方法名字为 getName 的,一个参数的方法
Method m = stuClass.getMethod("getName", String.class);
//创建一个对象实例
Object obj = stuClass.getConstructor().newInstance();
Object result = m.invoke(obj, "刘德华");
Log.e("ReflectDemo", "show()方法的返回值:" + result);
//获取共有方法
Method m2 = stuClass.getDeclaredMethod("getAge", int.class);
Object result2 = m2.invoke(obj, 12);
Log.e("ReflectDemo", "getAge()方法的返回值:" + result2);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void inject4(Activity activity) {
try {
//获取字节码
// Class stuClass = Class.forName("com.ml.maskpro.ui.MainActivity");
Class stuClass = activity.getClass();
//创建一个对象实例
Object obj = stuClass.getConstructor().newInstance();
//获取共有方法
Method m = stuClass.getDeclaredMethod("getAge", int.class);
m.setAccessible(true);//私有方法需要解除私有限制
Object result = m.invoke(obj, 12);
Log.e("ReflectDemo", "getAge()方法的返回值:" + result);
} catch (Exception e) {
e.printStackTrace();
}
}
打印结果:
03-06 11:20:46.323 10524-10524/com.ml.maskpro.debug E/ReflectDemo: show()方法的返回值:刘德华的歌迷
03-06 11:20:46.323 10524-10524/com.ml.maskpro.debug E/ReflectDemo: getAge()方法的返回值:歌迷的年龄12
反射必用方法
通过以上的代码,我们触及了一些新的方法,让我们现在学习下这些在反射中使用的方法:
1)使用反射,首先需要获取对类的字节流
// 通过对象获取
Student stu1 = new Student();
Class stuClass = stu1.getClass();
//“静态”的class属性
Class stuClass2 = Student.class;
//真实路径,就是带包名的类路径,包名.类名
Class stuClass3 = Class.forName("fanshe.Student");
2)执行类的构造函数
public static void inject() {
try {
//获取字节流
Class clazz = Class.forName("com.ml.butterknifelib.Demo");
/**
* 调用公有
*/
//所有公有构造方法 但不执行构造方法
Constructor[] conArray = clazz.getConstructors();
for(Constructor con : conArray){
Log.e("ReflectDemo",con.getName());
//执行构造方法,创建对象 ,没有返回值但时候返回null
Object obj = con.newInstance();
}
/**
* 调用私有一个参数的构造函数
*/
Constructor cone = clazz.getDeclaredConstructor(String.class);
cone.setAccessible(true);//暴力访问(忽略掉访问修饰符)
cone.newInstance("男");
} catch (Exception e) {
e.printStackTrace();
}
}
public class Demo {
public Demo() {
Log.e("ReflectDemo", "Demo 的构造函数被执行");
}
private Demo(String name) {
Log.e("ReflectDemo", "Demo 的构造函数被执行=" + name);
}
}
执行结果:
03-06 14:36:59.920 11800-11800/com.ml.maskpro.debug E/ReflectDemo: com.ml.butterknifelib.Demo
03-06 14:36:59.920 11800-11800/com.ml.maskpro.debug E/ReflectDemo: Demo 的构造函数被执行
03-06 14:36:59.921 11800-11800/com.ml.maskpro.debug E/ReflectDemo: Demo 的构造函数被执行=男
方法解析:
方法 | 解析 |
---|---|
getConstructors() | 获取 所有"公有的"构造方法 |
getDeclaredConstructors() | 获取所有的构造方法(包括私有、受保护,公有) |
getConstructor() | 获取"公有的"构造方法 |
getDeclaredConstructor() | 获取 构造方法 |
| 执行构造函数 |
3)获取类的成员变量
/**
* 给类中的变量赋值
*/
Field fied = clazz.getField("name"); //获取name参数
Object obj = clazz.getConstructor().newInstance(); //执行构造函数,获取类实例
fied.set(obj, "刘德华"); //给该name参数赋值
Demo demo = (Demo)obj;
Log.e("ReflectDemo","参数:"+demo.name);
方法解析:
返回 | 方法 | 说明 |
---|---|---|
Field[] | getFields() | 获取所有公有的字段 |
Field | getField(" ") | 获取指定字段 |
field.set(obj, "刘德华") | 给参数赋值,obj是对象 | |
setAccessible(true) | 解除私有限制 |
4)获取成员方法并调用
public static void inject() {
try {
//获取字节流
Class clazz = Class.forName("com.ml.butterknifelib.Demo");
/**
* 执行类中的方法
*/
Method m = clazz.getMethod("show", String.class);
//实例化一个Student对象
Object object = clazz.getConstructor().newInstance();
Object result = m.invoke(object, "刘德华");
Log.e("ReflectDemo", "返回=" + result.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
。。。。
public String show(String s) {
Log.e("ReflectDemo", "调用了:公有的,String参数的show1(): s = " + s);
return "成功";
}
执行结果:
03-06 15:25:02.762 12768-12768/com.ml.maskpro.debug E/ReflectDemo: 调用了:公有的,String参数的show1(): s = 刘德华
03-06 15:25:02.762 12768-12768/com.ml.maskpro.debug E/ReflectDemo: 返回=成功
返回 | 方法 | 说明 |
---|---|---|
Method[] | getMethods() | 获取所有公有方法 |
Method[] | getDeclaredMethods() | 获取所有方法 |
Method | getMethod("方法名", "入参数类型") | 获取指定方法 |
Object | invoke(" "," ") | 执行该方法 |