java反射机制

java中的反射

什么是反射?

反射是java中非常强大的一个技术,甚至很多博客中称其为java中最强大的技术。

java的反射机制其实是java提供给开发者的一种动态获取信息,动态调用对象的机制,简单来说就是在运行状态中,对于任意一个类,都能知道这个类所有的属性和方法,对于任意一个对象,都能调用它任意一个方法和属性。

一个例子

上面这样说还是比较抽象,举一个简单的例子,当我们需要为某个需求定制接口供app调用时,比如说需要在android.os路径下新增一个HapticPlay类,这个类中实现了一个start方法,那么当我们在framework中添加好接口,编译通过之后,AndroidStudio一定是调用不到的,因为AndroidStudio中只有谷歌官方的接口,但是system.img中确实有了我们新增的接口,这个时候,我们就可以用反射来调用。

具体用法

反射的基本用法很简单,仍然以HapticPlayer类为例

  • 要调用一个类中的方法,首先需要获取到这个类,使用反射机制时,我们只需要知道包路径和包名即 可,根据上面的描述,包路径为android.os,包名为HapticPlayer,那么获取类只 需要一行代码
Class<?> clz = Class.forName("android.os.HapticPlayer");

Class类型大致可以按照C语言中的void *理解,如果这行代码没有抛异常的话,此时clz就代表我们的HapticPlayer类。

  • 获取到类之后需要获取类中我们想调用的方法
Method startMethod = clz.getMethod("start",int.class);

入口参数中,start代表要调用的方法名,int.class代表方法的入参为int类型,也就是说,我们要调用的方法为start(int a)

  • 接着就需要实例化这个类,
Constructor<?> hapticPlayerCon = clz.getDeclaredConstructor());

getDeclaredConstructor相当于调用HapticPlayer的构造函数,当构造函数有参时,比如int类型调用的方法就是getDeclaredConstructor(int.class),如果是参数类型是自定义数据结构,那么就是getDeclaredConstructor(Class.forName("xxx")),比如我这里的参数是android.os.DynamicEffect(新增的类),我就需要写成getDeclaredConstructor(Class.forName("android.os.DynamicEffect"))。此时,如果没有抛出异常,那么hapticPlayerCon相当于HapticPlayer类中入参为android.os.DynamicEffect的构造函数。

  • 这时,我们就可以利用构造函数实例化这个类,
Object hapticObj = hapticPlayerCon.newInstance();

此时,如果没有抛出异常,那么hapticObj相当于HapticPlayer类的一个实例,利用这个实例,我们就可以调用start方法。

  • 这时,我们调用
startMethod.invoke(hapticObj, var);

就可以正常调用到start方法,invoke函数中,第一个参数是start方法所在的对象,第二个参数是start方法需要的参数,我这里是一个int

所以,整个函数是这样的

    public static void start (int loop) throws IllegalArgumentException,
            ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        @SuppressLint("PrivateApi")
        Class<?> clz = Class.forName("android.os.HapticPlayer");
        Method startMethod = clz.getMethod("start",int.class);
        @SuppressLint("PrivateApi")
        Constructor<?> hapticPlayerCon = clz.getDeclaredConstructor(Class.forName("android.os.DynamicEffect"));
        @SuppressLint("PrivateApi")
        Object hapticObj = hapticPlayerCon.newInstance();
        startMethod.invoke(hapticObj,loop);
    }

相比与之前的代码,这个函数中只是添加了throw异常和@SuppressLint("PrivateApi"),throw异常是为了当找不到这个类时app不会崩溃,@SuppressLint("PrivateApi")是为了屏蔽一些警告----Android10之后,反射不再是谷歌推荐的方法,Android11上,谷歌在framework限制了反射调用api,通过反射调用api时会抛出NoSuchMethod异常,这个问题可以看另一篇文档《Android11 apk中调用hide api》。

结语

反射是非常好用非常强大的机制,上面的介绍只是一点点皮毛。想要学学app的同事一定要重点关注这个机制,在定制接口、添加服务等场景下,一定会用到这个机制。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: Java反射机制是指在运行时动态地获取一个类的信息,并可以操作类的属性、方法和构造器等。Java反射机制可以使程序员在运行时动态地调用类的方法和属性,扩展类的功能,并可以实现注解、工厂模式以及框架开发等。 Java反射机制的原理如下:首先,Java编译器将Java源代码编译为字节码文件,字节码文件中包含着类的信息,这些信息包括类的名称、方法、属性和构造器等等。接着,Java虚拟机将字节码文件加载到内存中,然后通过类加载器将类加载到内存中形成一个类对象,这个类对象可以操作字节码文件中的信息。 使用Java反射机制的过程如下:首先获取类对象,通过类对象来获取类的构造器、属性、方法等信息,然后调用构造器来创建对象,通过属性获取和设置类的成员属性,通过方法调用类的方法等。 Java反射机制的优点是可以在运行时动态地得到类的信息,使得程序员在程序运行时能够对类进行更加灵活的操作,并可以使得程序更加通用化,同时也存在着一定的性能问题,因为Java反射机制需要Java虚拟机进行一定的额外处理,所以在程序运行时需要进行额外的时间和资源消耗。 总之,Java反射机制Java语言的一项重要特性,在Java开发中广泛应用,在代码编写、框架开发以及API开发中具有重要作用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值