反射的使用

初级:

当我们一开始使用反射的时候,首先理解的是,他可以拦截一个方法,并执行其方法。

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()获取 构造方法
newInstance()
执行构造函数

 

 

 

 

 

 

 

 

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()获取所有公有的字段
FieldgetField(" ")获取指定字段
 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()获取所有方法
MethodgetMethod("方法名", "入参数类型")获取指定方法
Objectinvoke(" "," ")执行该方法

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值