Android反射2-对反射语法的封装

2 对基本反射语法的封装

前面介绍的种种语法,无论是反射出一个类,还是反射出一个构造函数井调用它,都是为了进一步读写类的方法和宇段,所以我们只要封装以下几个方法即可:

  • 反射出 一个构造 函数并调用它 。
  • 调用静态方法。
  • 调用实例方法 。
  • 获取和设置一个字段的值。
  • 对泛型的处理 。

2.1 反射出一个构造函数

   public static Object createObject(String className, Class[] pareTyples, Object[] pareVaules) {
        try {
            Class r = Class.forName(className);
            Constructor ctor = r.getDeclaredConstructor(pareTyples);
            ctor.setAccessible(true);
            return ctor.newInstance(pareVaules);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
final String className = "xxx.xxx.TestClassCtor";

Class r = Class.forName(className);

 //含参
Class[] p3 = {int.class, String.class};
Object[] v3 = {1, "bjq"};
Object obj = RefInvoke.createObject(className, p3, v3);

//无参
Object obj2 = RefInvoke.createObject(className, null, null);

2.2 调用实例方法

    public static Object invokeInstanceMethod(Object obj, String methodName, Class[] pareTyples, Object[] pareVaules) {
        if(obj == null)
            return null;

        try {
            //调用一个private方法
            Method method = obj.getClass().getDeclaredMethod(methodName, pareTyples); //在指定类中获取指定的方法
            method.setAccessible(true);
            return method.invoke(obj, pareVaules);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
    //3.1.获取类的private实例方法,调用它
    public void test3() {
        try {
            //创建一个对象
            Class[] p3 = {int.class, String.class};
            Object[] v3 = {1, "bjq"};
            Object obj = RefInvoke.createObject(className, p3, v3);

            //调用一个private方法
            Class[] p4 = {String.class};
            Object[] v4 = {"jianqiang"};
            Object result = RefInvoke.invokeInstanceMethod(obj, "doSomething", p4, v4);

            Object a = result;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2.3 调用静态方法

    public static Object invokeStaticMethod(String className, String method_name, Class[] pareTyples, Object[] pareVaules) {
        try {
            Class obj_class = Class.forName(className);
            Method method = obj_class.getDeclaredMethod(method_name, pareTyples);
            method.setAccessible(true);
            return method.invoke(null, pareVaules);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
    //3.2.获取类的private静态方法,调用它
    public void test3_1() {
        try {
            Class[] p3 = {};
            Object[] v3 = {};
            RefInvoke.invokeStaticMethod(className, "work", p3, v3);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2.4 获取并设置一个字段的值

 public static Object getFieldObject(String className, Object obj, String filedName) {
        try {
            Class obj_class = Class.forName(className);
            Field field = obj_class.getDeclaredField(filedName);
            field.setAccessible(true);
            return field.get(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public static void setFieldObject(String classname, Object obj, String filedName, Object filedVaule) {
        try {
            Class obj_class = Class.forName(classname);
            Field field = obj_class.getDeclaredField(filedName);
            field.setAccessible(true);
            field.set(obj, filedVaule);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 //4.1.获取类的private实例字段,修改它
    public void test4() {
        try {
            //创建一个对象
            Class[] p3 = {int.class, String.class};
            Object[] v3 = {1, "fhx"};
            Object obj = RefInvoke.createObject(className, p3, v3);

            //获取name字段,private
            Object fieldObject = RefInvoke.getFieldObject(className, obj, "name");

            //只对obj有效
            RefInvoke.setFieldObject(className, obj, "name", "hongxue123");

            Object fieldObject2 = RefInvoke.getFieldObject(className, obj, "name");

            int a = 1;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    //获取类的private静态字段,修改它
    public void test4_1() {
        try {
            Object fieldObject = RefInvoke.getFieldObject(className, null, "address");
            RefInvoke.setFieldObject(className, null, "address", "ABCD");

            //静态变量,一次修改,终生受用
            TestClassCtor.printAddress();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2.5 对泛型类的处理

public class AMN {

    private static final Singleton<ClassB2Interface> gDefault = new Singleton<ClassB2Interface>() {
        protected ClassB2Interface create() {
            ClassB2 b2 = new ClassB2();
            b2.id = 2;
            return b2;
        }
    };

    static public ClassB2Interface getDefault() {
        return gDefault.get();
    }
}
class ClassB2 implements ClassB2Interface{
    public int id;

    public void doSomething() {
        Log.v("hongxue", "ClassB2 doSomething");
    }
}
public interface ClassB2Interface {
    void doSomething();
}

public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}
 public void test5() {
        try {
            //获取AMN的gDefault单例gDefault,gDefault是静态的
            Object gDefault = RefInvoke.getFieldObject("xxx.xxx.xxx.AMN", null, "gDefault");

            // gDefault是一个 android.util.Singleton对象; 我们取出这个单例里面的mInstance字段
            Object rawB2Object = RefInvoke.getFieldObject(
                    "xxx.xxx.xxx.Singleton",
                    gDefault, "mInstance");


            // 创建一个这个对象的代理对象ClassB2Mock, 然后替换这个字段, 让我们的代理对象帮忙干活
            Class<?> classB2Interface = Class.forName("xxx.xxx.xxx.ClassB2Interface");
            Object proxy = Proxy.newProxyInstance(
                    Thread.currentThread().getContextClassLoader(),
                    new Class<?>[] { classB2Interface },
                    new ClassB2Mock(rawB2Object));

            //把Singleton的mInstance替换为proxy
            RefInvoke.setFieldObject("xxx.xxx.xxx.Singleton", gDefault, "mInstance", proxy);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2.6 RefInvoke.java

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class RefInvoke {

    public static Object createObject(String className, Class[] pareTyples, Object[] pareVaules) {
        try {
            Class r = Class.forName(className);
            Constructor ctor = r.getDeclaredConstructor(pareTyples);
            ctor.setAccessible(true);
            return ctor.newInstance(pareVaules);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public static Object invokeInstanceMethod(Object obj, String methodName, Class[] pareTyples, Object[] pareVaules) {
        if(obj == null)
            return null;

        try {
            //调用一个private方法
            Method method = obj.getClass().getDeclaredMethod(methodName, pareTyples); //在指定类中获取指定的方法
            method.setAccessible(true);
            return method.invoke(obj, pareVaules);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public static Object invokeStaticMethod(String className, String method_name, Class[] pareTyples, Object[] pareVaules) {
        try {
            Class obj_class = Class.forName(className);
            Method method = obj_class.getDeclaredMethod(method_name, pareTyples);
            method.setAccessible(true);
            return method.invoke(null, pareVaules);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public static Object getFieldObject(String className, Object obj, String filedName) {
        try {
            Class obj_class = Class.forName(className);
            Field field = obj_class.getDeclaredField(filedName);
            field.setAccessible(true);
            return field.get(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public static void setFieldObject(String classname, Object obj, String filedName, Object filedVaule) {
        try {
            Class obj_class = Class.forName(classname);
            Field field = obj_class.getDeclaredField(filedName);
            field.setAccessible(true);
            field.set(obj, filedVaule);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值