在 Java 和 Android 中, 我们常常会使用反射来达到一些兼容的目的. Java 原生提供的反射很是麻烦, 使用起来很是不方便. 比如我们想要调 UserManager 的静态方法 get, 使用原生的实现如下
- try {final Method m = UserManager.class.getMethod("get", Context.class);
- m.setAccessible(true);
- m.invoke(null, this);
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
实现起来好不麻烦. 这其中
需要确定方法名和参数来获取对应的 Method 对象
设置 Method 对象的 assessible 为 true
调用 invoke 方法, 并且传入对应的参数
捕获其中可能抛出来的一连串异常
那么反射能简单点么, 当然, 而且还会简单很多.
这就是本文想要介绍的, jOOR(Java Object Oriented Reflection), 它是一个对 java.lang.reflect 包的简单封装, 使得我们使用起来更加直接和方便.
使用 jOOR, 上面的代码可以缩短成一行.
Reflect.on(UserManager.class).call("get", getApplicationContext());
依赖
jOOR 没有依赖.
使用 jOOR 只需要将这两个文件(Reflect.java,ReflectException.java), 加入工程即可.
API 介绍
Reflect
Reflect.on 包裹一个类或者对象, 表示在这个类或对象上进行反射, 类的值可以使 Class, 也可以是完整的类名(包含包名信息)
Reflect.create 用来调用之前的类的构造方法, 有两种重载, 一种有参数, 一种无参数
Reflect.call 方法调用, 传入方法名和参数, 如有返回值还需要调用 get
Reflect.get 获取 (field 和 method 返回) 值相关, 会进行类型转换, 常与 call 和 field 组合使用
Reflect.field 获取属性值相关, 需要调用 get 获取该值
Reflect.set 设置属性相关.
ReflectException
引入 ReflectException 避免了我们去 catch 过多的异常, 也减少了纵向代码量, 使得代码简洁不少. ReflectException 抛出, 可能是发生了以下异常.
- ClassNotFoundException
- IllegalAccessException
- IllegalArgumentException
- InstantiationException
- InvocationTargetException
- NoSuchMethodException
- NoSuchFieldException
- SecurityException
除此之外, ReflectException 属于 unchecked 异常, 语法上不需要显式进行捕获, 但是也需要根据实际情况, 斟酌是否进行显式捕获该异常.
使用示例
创建实例
String string = Reflect.on(String.class).create("Hello World").get();
访问属性(public,protected,package,private 均可)
char pathSeparatorChar = Reflect.on(File.class).create("/sdcard/droidyue.com").field("pathSeparatorChar").get();
修改属性(final 属性也可以修改)
String setValue = Reflect.on(File.class).create("/sdcard/drodiyue.com").set("path", "fakepath").get("path");
调用方法(public,protected,package,private 均可)
- ArrayList arrayList = new ArrayList();
- arrayList.add("Hello");
- arrayList.add("World");
- int value = Reflect.on(arrayList).call("hugeCapacity", 12).get();
实现原理
Reflect 实际是对原生 java reflect 进行封装, 屏蔽了无关细节.
以 fields 方法为例, 其内部实现可以看出是调用了 java 原生提供的反射相关的代码.
- public Map fields() {
- Map result = new LinkedHashMap();
- Class type = type();
- do {
- for (Field field : type.getDeclaredFields()) {
- if (!isClass ^ Modifier.isStatic(field.getModifiers())) {
- String name = field.getName();
- if (!result.containsKey(name))
- result.put(name, field(name));
- }
- }
- type = type.getSuperclass();
- } while (type != null);
- return result;
- }
库地址
以上就是这些, 希望 jOOR 可以对大家的开发日常有所帮助.
来源: http://www.jianshu.com/p/3721628f224d