Android之反射机制

1.疑问

在进行Android应用编写的过程中,常常听到专业术语"反射机制",是否也有同样的以下几点疑问

  • A. 反射机制是什么?

  • B. 反射机制能带来什么好处?

  • C. 反射机制怎么使用?具体有什么方法?

2.Java的编译运行过程

在了解反射机制前,我们先了解下JAVA的编译运行过程,也就是经常提到的一次编译到处执行,如下:

  • .java的源代码文件被编译成.class文件字节码
  • JVM中的类加载器加载各个类.class字节码文件
  • 加载完毕之后,字节码在JAVA虚拟机JVM中执行

例如:

Class类的对象表示正在运行的Java程序中的类或接口,也就是任何一个类被加载时,即将类的.class文件(字节码文件)读入内存的同时,都自动为之创建一个java.lang.Class对象。

Class类没有公共构造方法,其对象是JVM在加载类时通过调用类加载器中的defineClass()方法创建的

3.Java反射机制

在了解JAVA编译运行过程后,下面我们来看看对于开篇提到的反射机制的几个问题

  • A. 反射机制是什么?

反射机制就是对编译后的.class字节码进行解剖,解剖出方法(构造方法等),成员变量、修饰符等,在解剖先加载相关类的字节

  • B. 反射机制能带来什么好处?

因为通过编译后的.class文件仅有public方法,对于隐藏的方法及静态修饰的变脸或方法,可以使用反射机制调用,从而可以更快捷的实现功能

  • C. 反射机制怎么使用?具体有什么方法?

关于反射机制具体如何使用及具体的方法,先了解以下相关内容,在最后章节中举例说明

3.1 获取类的对象

Java中,每个class都有一个相应的Class对象。也就是说,当我们编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息。

反射机制获取类的对象三种方法:

  • 通过forName方法获取
Class c = Class.forName("类名")
  • 通过class属性获取
Class c = 类名.class
  • 通过getClass属性获取
类名 对象=new 类名()
Class c = 对象.getClass

3.2 获取类的变量(成员变量)

Field类

3.3 获取类的方法

Method类:代表类的方法

  • 获取所有的方法
getDeclaredMethods()
getDeclaredMethod("方法名",参数类型.class,……)
  • 获得方法的放回类型

getReturnType()
  • 获得方法的传入参数类型
getParameterTypes()

3.4 获取构造方法

Constructor类:代表类的构造方法

  • 获取所有的构造方法
getDeclaredConstructors()
  • 获取特定的构造方法
getDeclaredConstructor(参数类型.class,……)

4.举例

长按关机键关机,shutdown方法,通过源码发现,此方法为隐藏hide方法

Android之反射机制_第1张图片

如果要使用此方法,则必须使用反射机制

      PowerManager powerManager = (PowerManager)getSystemService(POWER_SERVICE);
            Class c =  powerManager.getClass();
            try {
                Method m = c.getMethod("shutdown",boolean.class,String.class,boolean.class);
                m.invoke(powerManager,confirm,wait,false);
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }

4.1 反射机制实现:

代码段如下

    public void shutdown(boolean confirm, boolean wait)
            throws RemoteException
    {
        PowerManager powerManager = (PowerManager)getSystemService(POWER_SERVICE);
        Class c =  powerManager.getClass();
        try {
            Method m = c.getMethod("shutdown",boolean.class,String.class,boolean.class);
            m.invoke(powerManager,confirm,wait,false);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }

  • step1

加载相应类,即获取运行时类对象

Class c =  powerManager.getClass();
  • step2

获取shutdown方法,有三个参数,分别为boolean/string/boolean类型,getMethod的第一个参数为方法名

Method m = c.getMethod("shutdown",boolean.class,String.class,boolean.class);
  • step3

最后使用invoke方法进行反射,其中invoke的第一个参数为对象,后面的参数为具体的参数

 m.invoke(powerManager,confirm,wait,false);

你可能感兴趣的:(Android)