android java反射机制_Java中的反射机制

Android开发中的热修复涉及到反射及类的加载等,因此先回顾一下java的反射,关于反射的定义及作用等引用博客“https://www.cnblogs.com/Eason-S/p/5851078.html”中的话。

说明:上述链接的标题四中的第【8】条描述有误,已经在留言中指出,详情也可查看本文“反射的例子”的标注说明。

一、Java反射机制:

主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。在java中,只要【给定类的名字】, 那么就可以通过反射机制来获得类的所有信息。

二、作用:

1、在运行时判断任意一个对象所属的类;

2、在运行时获取类的对象;

3、在运行时访问java对象的属性,方法,构造方法等。

三、优缺点:

优点:

1、可以实现动态创建对象和编译,体现出很大的灵活性。

2、对于JAVA这种先编译再运行的语言来说,反射机制可以使代码更加灵活,更加容易实现面向对象。

缺点:

1、对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。

四、反射的应用场景:

1、该类的某个方法是在高版本新增的,例如MediaRecorder.java在Android6.0以后新增了resume()方法用于暂停后的再次录制,此时项目为了兼容低版本则可以判断当版本>=6.0时调用该

方法,但是为了能在6.0以下的开发环境中编译通过,可以使用反射调用该方法。----------仅作为例子说明,实际开发中编译环境一般都会超过6.0。

2、关于Handler机制中消息的同步分隔栏,需要通过postSyncBarrier()设置:该方法属于隐藏方法hide在API23之前,该方法需要通过Looper调用;从API23开始,源码去掉了Looper中的方法,此时只能通过MessageQueue调用;但无论上述哪种,都需要通过反射调用;

例如:MessageQueue类只有带参的构造函数,因此需要先getDeclaredConstructor(),然后再创建实例。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 //方式一:

2 Class> looperCls = Class.forName("android.os.MessageQueue");3 Constructor> constructor = looperCls.getDeclaredConstructor(boolean.class);4 constructor.setAccessible(true); //设置可访问

5

6 Method method = looperCls.getMethod("postSyncBarrier");7 method.invoke(constructor.newInstance(true)); //根据带参的构造函数创建实例并调用

8

9 postSyncBarrier函数10

11

12 //方式二:

13 Looper looper =getMainLooper();14 MessageQueue queue =looper.getQueue();15 Method methodSync = queue.getClass().getMethod("postSyncBarrier");16 methodSync.invoke(queue);

View Code

五、反射的例子

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecom.test.pattern;2

3 importjava.lang.reflect.Constructor;4 importjava.lang.reflect.Field;5 importjava.lang.reflect.Method;6 importjava.util.Collection;7

8 public class TestReflect extendsObject{9

10 /**

11 *@paramargs12 */

13 public static voidmain(String[] args) {14 //TODO Auto-generated method stub

15 try{16 Class> mClass = Class.forName("com.test.pattern.Child");17

18 Field[] childFields =mClass.getDeclaredFields();19

20 System.out.println("---------mClass.getDeclaredFields():--------- ");21

22 for(Field field : childFields) {23 int mod =field.getModifiers();24 Class> type =field.getType();25 String name =field.getName();26

27 System.out.println(mod + " name: " + name + " type: " +type);28 }29

30 System.out.println("\n--------- mClass.getFields(): ---------");31

32 Field[] fields = mClass.getFields(); //注意点

33

34 for(Field field : fields) {35 int mod =field.getModifiers();36 Class> type =field.getType();37 String name =field.getName();38

39 System.out.println(mod + " name: " + name + " type: " +type);40 }41

42 System.out.println("\n--------- mClass.getDeclaredMethods()---------");43

44 Method[] methods =mClass.getDeclaredMethods();45 for(Method method : methods) {46 try{47

48 if("childMethod".equals(method.getName())){49 method.setAccessible(true); //设置可访问-------

50 Constructor> constructor = mClass.getDeclaredConstructor(String.class);51 Object obj = method.invoke(constructor.newInstance("use_in_reflect"));52 System.out.println("obj: " +obj);53 }54

55 } catch(Exception e) {56 //TODO Auto-generated catch block

57 e.printStackTrace();58 }59 }60

61 } catch(ClassNotFoundException e) {62 e.printStackTrace();63 }64

65 }66

67

68 }69

70

71 interfaceParent{72 //public static final

73 String pName = "inter";74

75 voidmethodInter();76 }77

78 class Child implementsParent{79

80 private String cName = "childName";81

82 public String pro = "pro"; //注意点

83

84 String def = "default";85

86 public int count = 10; //注意点

87

88 Child(String name) {89 //TODO Auto-generated constructor stub

90 this.cName =name ;91 }92

93

94 @Override95 public voidmethodInter() {96 //TODO Auto-generated method stub

97 System.out.println("print_pName: " +pName);98 }99

100 privateString childMethod(){101 String m = "method_of_child " +cName;102 returnm;103 }104

105 }106

107

108 //运行结果:

109 /*

110

111 ---------mClass.getDeclaredFields():---------112 2 name: cName type: class java.lang.String113 1 name: pro type: class java.lang.String114 0 name: def type: class java.lang.String115 1 name: count type: int116

117 --------- mClass.getFields(): ---------//注意点118 1 name: pro type: class java.lang.String119 1 name: count type: int120 25 name: pName type: class java.lang.String121

122 --------- mClass.getDeclaredMethods()---------123 obj: method_of_child use_in_reflect124

125 */

View Code

重点说明一下方法getFields():获取公有属性,即获取的不仅仅是父类属性,还包括类本身public类型的属性。看“注意点”的运行结果即可知道。

官方介绍:

/* Returns an array containing {@code Field} objects reflecting all

* the accessible public fields of the class or interface represented by

* this {@code Class} object.

*/

六、参考文章:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值