1.疑问
在进行Android应用编写的过程中,常常听到专业术语"反射机制",是否也有同样的以下几点疑问
- A. 反射机制是什么?
- B. 反射机制能带来什么好处?
- C. 反射机制怎么使用?具体有什么方法?
在了解反射机制前,我们先了解下JAVA的编译运行过程,也就是经常提到的一次编译到处执行,如下:
.java
的源代码文件被编译成.class
文件字节码JVM
中的类加载器加载各个类.class
字节码文件- 加载完毕之后,字节码在JAVA虚拟机
JVM
中执行
例如:
Class
类的对象表示正在运行的Java程序中的类或接口,也就是任何一个类被加载时,即将类的.class
文件(字节码文件)读入内存的同时,都自动为之创建一个java.lang.Class
对象。
3.Java反射机制Class
类没有公共构造方法,其对象是JVM在加载类时通过调用类加载器中的defineClass()
方法创建的
在了解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之反射机制】
文章图片
如果要使用此方法,则必须使用反射机制
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);