Android反射(Reflect)完全解析--强势来袭 - Go语言中文社区

Android反射(Reflect)完全解析--强势来袭



        贯穿整个深圳的深南大道,也是最繁忙的路,贯穿深圳的几个区,在这条道上有著名的景点和商业圈和IT公司,今天先来腾讯!




什么是反射?

官方一点的解释:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 
     然而在android中Google很多的类的某些方法不让第三方应用去调用,通过java反射机制能把这些隐藏方法获取出来并调用,三方应用上我们就很方便的去用这些方法。 


为什么要使用反射?

优点: 

(1)能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性。 
(2)与Java动态编译相结合,可以实现无比强大的功能 

如果不适用反射,那么你就只能写死到代码里了。
所以说,一个灵活,一个不灵活。
很少情况下是非用反射不可的。大多数情况下反射是为了提高程序的灵活性。
因此一般框架中使用较多。因为框架要适用更多的情况。对灵活性要求较高。

缺点: 
(1)使用反射的性能较低 
(2)使用反射相对来说不安全 
(3)破坏了类的封装性,可以通过反射获取这个类的私有方法和属性 

反射的使用和对比

/**
 * 通过反射得到对象,知道类的名字,通过方法统一得到对象
 * @param name
 * @return
 */
public Hero getHeroByReflect(String name) {
    try {
        Class<?> cls = Class.forName(name);
        Hero hero = (Hero) cls.newInstance();
        hero.attach();
        return hero;
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;

}


/**
 * 通过new的方式得到对象
 */
public void getHeroByNew(){
    Hero Person = CreateHero("Person");
    Person.attach();

}

/**
 * 多个实现类,必须通过判断来区分产出哪个实例
 * @param name
 * @return
 */
public Hero CreateHero(String name) {
    if ((name).equals("Children")) {
        return new Children();
    }
    if ((name).equals("Person")) {
        return new Person();
    }
    return null;
}

interface Hero {
    public void attach();
}

//static
static class Children implements Hero {

    //反射需要无参的构造函数,否则异常
    //cls.newInstance()默认返回的是Person类的无参数构造对象
    // 被反射机制加载的类必须有无参数构造方法,否者运行会抛出异常

    public String name;

    public Children() {

    }

    public void setName(String tempName){
        name=tempName;
    }

    @Override
    public void attach() {
        Log.d("Main","Children");
    }
}

class Person implements Hero {

    @Override
    public void attach() {
        Log.d(TAG,"Person");
    }
}

反射需要掌握的方法:


方法关键字 含义
getDeclareMethods() 获取所有的方法
getReturnType() 获取方法的返回值类型
getParameterTypes() 获取方法的传入参数类型
getDeclareMethod("方法名,参数类型.class,....") 获得特定的方法
  -
构造方法关键字 含义
getDeclaredConstructors() 获取所有的构造方法
getDeclaredConstructors(参数类型.class,....) 获取特定的构造方法
  -
成员变量 含义
getDeclaredFields 获取所有成员变量
getDeclaredField(参数类型.class,....) 获取特定的成员变量
  -
父类和父接口 含义
getSuperclass() 获取某类的父类
getInterfaces() 获取某类实现的接口

    /**
     * 反射常用的的类,方法,变量
     */
    public void reflectMethod(String name){
        try {

            /**
             * 类解析
             */
            Class<?> cls = Class.forName(name);//通过类名加载Children//            Class<? > clazz = activity.getClass();//通过一个类得到

            Hero hero = (Hero) cls.newInstance();//实例化Children
            Method setname=cls.getDeclaredMethod("setName", String.class);//获取声明的方法setName(),方法名和传值的类型值
            setname.invoke(hero, "children");//执行方法,设置调用setName的对象和传入setName的值

            /**
             * 方法解析
             */
            Method[] methods = cls.getMethods();//得到所有的方法
            Method method=methods[0];
            method.setAccessible(true);//提高加载的速度,能高20            method.invoke(hero, String.class);//方法的执行


            /**
             *方法的参数类型
             */
            method.getParameterTypes();//获取方法的传入参数类型
            method.getReturnType();//获取方法的返回值类型

            /**
             * 变量解析
             */
            Field[] fields = cls.getFields();//得到所有的成员变量
            Field field=fields[0];
            field.setAccessible(true);//设置为私有
            field.set(cls, "");//给成员变量设置值

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


注意:
cls.newInstance()方法返回的是一个泛型T,我们要强转成Person类
cls.newInstance()默认返回的是Person类的无参数构造对象
被反射机制加载的类必须有无参数构造方法,否者运行会抛出异常


AS源代码地址:不知道为什么被删了哭,我会在评论里面把它添加进来
  
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/WHB20081815/article/details/61198050
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-04-19 12:48:01
  • 阅读 ( 666 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢