简要介绍Android反射使用

简要介绍Android反射原理

  在这篇文章中简要对反射原理进行讲解,希望能够通过这篇文章对反射原理有一个归纳性的了解,并掌握一定的使用方式。
  首先,我们来了解下,什么是反射?
  实际上Android的反射原理也是基于Java本身的一个反射机制。主要是指可以通过代码程序进行访问、检测和修改它本身状态或行为的一种能力。
  那么如何获取反射的类或者方法呢,下面就简要的讲诉下获取反射的主要方法。

通过反射加载类

  如下我们可以通过JVM对我们想要的类进行查找,然后将获得的Class对象进行加载,这样我们就能获取到一个简要的Class类的对象了,并通过调用newInstance()方法让加载完的类在内存中创建对应的实例,并把实例赋值给我们要进行查找的类。
方式1
  通过Class的forName方法的进行反射获取的源码例子如下:

Class<?> cls=Class.forName("com.test.PackageNameTest"); //forName(包名.类名)
PackageNameTest test=(PackageNameTest)cls.newInstance();

  在这里需要先引入一个概念,就是类加载概念,当使用一个类的时候(比如new一个类的实例),jvm会检查此类是否被加载到内存,如果没有,则会执行加载操作,加载操作的内容是,读取类对应的class文件数据,解析此数据,构造一个此类对应的Class类的实例,此Class类的实例描述了类的结构,并且提供了调用此类成员的接口。此时jvm就可以使用该类了,比如实例化此类,或者调用此类的静态方法。
  而我们这里使用的forName方法其实就是JVM类加载中的手动加载方法,目的都是为了获取这个类的实例。其中,在金使用这个类前都会默认进行类初始化,类初始化操作就是执行一遍类的静态语句,包括静态变量的声明还有静态代码块。稍微注意的是,这里并不包括静态方法。
  那么除了通过forname的方式获取到类还可以通过getClass和ClassLoad进行装载。
  ClassLoad方式装载

PackageNameTest t = new PackageNameTest();
Class<?> cls=t.getClass();//getClass 方式,返回类对象运行时真正所指的对象,所属类型的Class对象
PackageNameTest tt=(PackageNameTest)cls.newInstance();

  getClass方式装载

Class<?> cls=PackageNameTest.Class();//.class 方式,ClassLoader 装载入内存,不对类进行类的初始化操作
PackageNameTest t=(PackageNameTest)cls.newInstance();

通过反射加载函数

  其实和前面加载类的方式相似,可以通过get的方式进行对应类型的获取。首先先获取这个类,我这里依照方法,和变量名举个例子:
  如下为反射构造函数:

		Class c1 = PackageNameTest.class;
        // getConstructor(Class[] params) 根据构造函数的参数,返回一个具体的具有public属性的构造函数
        try {
            Constructor constructor1 = c1.getConstructor(String.class);
        } catch (NoSuchMethodException e) {	//没此函数的异常捕获
            e.printStackTrace();
        }

  如下为反射方法:

		Class c2 = PackageNameTest.class;
        // 根据方法名和参数,返回一个具体的具有public属性的方法
        try {
            Method method1 = c2.getMethod("testPublicVoidMethod", null);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

  如下为反射变量:

        Class c3 = PackageNameTest.class;
        // getField(String name) 根据变量名,返回一个具体的具有public属性的成员变量
        try {
            Field field1 = c3.getField("mPublicStr");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

  那么通过这些方式就可以在Android中简要通过反射来获取自己想要的类,方法,变量等等。可能这里不禁会产生一个问题,为什么要通过反射来获取,直接new一个,它不香吗?
  我们来看看下面这这张图:
JVM运行
  上面这张是Java的内存模型图,在程序运行时,Jvm会将方法,类进行加载创建放入内存区。当然,在加载前会先检查类是否加载,寻找类对应的class对象,若加载好,则为你的对象分配内存,初始化也就是之前说的new一个对象。但这里的对象创建是在程序初始化的时候进行的,我们不可能在运行的时候还可以进行这样的操作。
  为了更好的说明,我这边举个常用的例子,数据库在进行驱动加载的时候,可能会发现加载的这个驱动类不是我目前所需要的,那么如何将它变成我需要的,这时候反射就派上用场了。又或者说,很多时候的源代码我们是获取不到的,那么利用反射创建一个类,而反射需要的参数是一个字符串,我们将字符串存入配置文件中,这样,我们修改配置文件即可动态产生不一样的代码了,为了适应各种需求,这种情况在很多框架中常常出现。

反射常用方法

  如下为在反射中会常常用到的一些方法,可以通过这些方法更好的获取我们想要的一些内容。

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

  到此就是简要介绍在Android中的反射简单使用和原理介绍了,欢迎讨论交流。

参考文章

Android 反射机制的理解
https://www.jianshu.com/p/7fdb8c828602
Android 反射机制
https://www.jianshu.com/p/88ecd6e1a28b

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值