项目经理觉得最近在做的一个项目Toast提示应该在用户正确输入后再消失,这个需求还算比较怪异哈。上网搜了下能可以使用Java的反射机制来实现,而且反射还能调用很多Android SDK的内部隐蔽方法,顿觉反射真是很有爱的东西。


首先来看看度娘给出的定义。

反射定义:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射用途:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

其中上文中的所谓动态就是:程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言,那么Java就不是动态语言了。但Java有个类似的实现机制就是反射,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。


Android开发时反射能帮助我们多少?
1. 有些网友可能发现Android的SDK比较封闭,很多敏感的方法常规的用户无法编译,我们如果翻看了代码直接在反射中声明动态调用即可。比如很多internal或I开头的AIDL接口均可以通过反射轻松调用。

2. 反射对于Android来说更重要的是考虑到应用的兼容性,我们目前主要兼容从Android 4.0到5.0的项目,API Level从14到21可以方便的扩充,调用前我们预留一个标志位声明该API的最低以及最高的API Level为多少可以调用。

3. 对于调试Java的反射是功臣了,在Logcat中我们可以看到出错的地方肯定有类似java.lang.reflect.XXX的字样,这种自检机制可以帮助我们方便的调试Android应用程序。

反射的缺点有哪些?

1. 因为是动态执行的,效率自然没有预编译时引用现有的库效率高,就像平时我们Win32开发时,可以不用h文件,直接通过GetProcAddress一样去动态获取方法的地址。当然效率要根据复杂程度而决定,一般稍微复杂的处理性能损失可能超过20%,对于一些复杂的涉及Java自动类型转换判断,执行时间可能是直接引用的上千倍,所以最终我们调试时必须考虑性能问题。能不用就不用。

2. 因为反射是动态的,所以需要处理很多异常,不然Dalvik崩溃出Force Close的概率会大很多,很简单的一个反射就需要至少3个异常捕获,一把需要捕获以下异常:ClassNotFoundException, IllegalAccessException,
            InstantiationException, SecurityException, NoSuchMethodException,
            IllegalArgumentException, InvocationTargetException ,而且本身try-catch效率就不是很高,自然进一步影响运行效率,对于Android开发我们必须考虑这些问题。

3. 反射因为导致代码臃肿,自然稍微复杂的几个方法实用反射将会导致代码可读性和维护性降低,如果很抽象的调用不推荐这种方法。



先给出一利用反射调用调用package里类方法的Demo refer:http://terryblog.blog.51cto.com/1764499/377399/



首先我们定义一个类,此为只是简单的定义几个方法,即加减乘除四个方法,代码如下:
class operationClass {

     public float add(int parm1, int parm2) {
         return parm1 + parm2;
     }

     public float cut(int parm1, int parm2) {
         return parm1 - parm2;
     }

     public float ride(int parm1, int parm2) {
         return parm1 * parm2;
     }

     public float Except(int parm1, int parm2) {
         return parm1 / parm2;
     }
 }

调用方法如下:

  • 获取相应的类对象名称