Android的反射机制的实现

在Android中会有一些异常方法或者属性,是你想用而拿不到的,这种时候你就需要使用反射了,反射不能跨进程使用

反射机制:(官方解释)

  • 在运行状态中,对于任意一个类或者任意一个对象,都能够知道这个类的所有属性和方法,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制

反射原理:(以下仅是我个人理解,如有误请帮忙指正,谢谢)

  • java中的类运行后JVM会在本地生成一个class文件,而反射则是去加载这个文件,读取里面的信息,解析里面的代码

反射的简单应用

首先我在本地新建了一个类TestFanshe.java,里面只有一个方法

    public String getString(String s){
        return s + "码农";
    }

然后我再用反射的方法去拿到类对象,然后通过反射的方法调用类里面的方法,拿到返回值

Class<?> aClass = null;
try {
  aClass = Class.forName("com.weidu.plugincityassistant.TestFanshe");
  Object o1 = ReflexUtils.setMethod(aClass.newInstance(),"getString", false, "我是一个");
  Log.i("test_fanshe","o1 = " + o1.toString());
} catch (ClassNotFoundException e) {
   e.printStackTrace();
} catch (IllegalAccessException e) {
   e.printStackTrace();
} catch (InstantiationException e) {
   e.printStackTrace();
}

最后的打印结果为 “我是一个码农”

这段代码中,首先是通过Class.forName()方法,传入所需要的这个类的全类名(全类名是这个类的包名加上类名),返回类对象aClass,然后通过setMethod方法调用了这个类的方法并拿到返回值o1,这个值是object类型的,需要强转为string类型,再来解析setMethod方法

  public <T> T setMethod(Object obj, String method, boolean isObject, Object ... vlaue){
        return setMethod(obj, obj.getClass(), method, isObject, vlaue);
    }

    /**
     *
     * @param obj 对象
     * @param cls  对象class
     * @param method 方法名
     * @param isObj 是否执行到Objcet
     * @param vlaue 方法参数
     * @param <T>
     * @return
     */
    public <T> T setMethod(Object obj, Class cls, String method, boolean isObject, Object ... vlaue){
        try {
            Class[] classes = new Class[vlaue.length];
            for (int i = 0; i < vlaue.length; i++) {
                classes[i] = vlaue[i] == null ? Object.class : vlaue[i].getClass();
            }
            Method m = cls.getDeclaredMethod(method, classes);
            m.setAccessible(true);
            return (T) m.invoke(obj, vlaue);

        } catch (NoSuchMethodException e) {
            if (cls.getSuperclass() != null && (isObject || cls.getSuperclass() != Object.class)){
                return setMethod(obj, cls.getSuperclass(), method, isObject, vlaue);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }

这里面 每个参数的意思上面都有就不一一解说了,通过这样,我们就可以实现通过反射的形式拿到类并调用里面的方法了

附上反射的三种实现方式

  • 通过全类名
Class<?> aClass = Class.forName("packagename.TestFanshe");
  • 指定类型的class对象

Class<?> cls=TestFanshe.Class();
TestFanshe t =(TestFanshe)cls.newInstance();

  • 通过getClass()方式

TestFanshe test = new TestFanshe();
Class<?> cls=test .getClass();
TestFanshe test2=(TestFanshe)cls.newInstance();

三种方式个人推荐优选第一种,当你当前都拿不到这个类但是知道这个类的全类名的时候,二三种就起不到作用了

关于Class<?> cls=Class.forName("fanshe.Person");cls内部有哪些方法供我们使用

好了,反射就讲解这些了,如有更多见解的,请在下方留言,互相学习

猜你喜欢

转载自blog.csdn.net/lovelixue/article/details/82757178
今日推荐