概要:简单优雅的使用反射。
  本文的例子都可以在示例代码中看到并下载,如果喜欢请star,如果觉得有纰漏请提交issue,如果你有更好的点子可以提交pull request。本文的示例代码主要是基于jOOR行编写的,如果想了解更多请查看这里的测试代码。
  一、需求
  一个“懒”程序员突然跑过来说:“反射好麻烦,我要提点需求。”
  听到这句话后我知道,一定不好过了,奇葩需求又来了。
  我们之前写反射都是要这么写:
  public static <T> T create(HttpRequest httpRequest) {
  Object httpRequestEntity = null;
  try {
  Class<T> httpRequestEntityCls = (Class<T>) Class.forName(HttpProcessor.PACKAGE_NAME + "." + HttpProcessor.CLASS_NAME);
  Constructor con = httpRequestEntityCls.getConstructor(HttpRequest.class);
  httpRequestEntity = con.newInstance(httpRequest);
  } catch (ClassNotFoundException e) {
  e.printStackTrace();
  } catch (InstantiationException e) {
  e.printStackTrace();
  } catch (IllegalAccessException e) {
  e.printStackTrace();
  } catch (NoSuchMethodException e) {
  e.printStackTrace();
  } catch (InvocationTargetException e) {
  e.printStackTrace();
  }
  return (T) httpRequestEntity;
  }
  因为反射在开发中很少用(做普通的业务开发的话),仅仅在自己写一些框架和注解框架时会用到,所以对api总是不熟悉。每次用到api都要去网上查,查了后又得自己实验下,很不爽。更差劲的是这样写法可读性十分低下。我不希望这样写反射,我希望反射能像
  String str = new String();
  这样简单,一行代码搞定!。
  此外,有很多人都说反射影响性能,在开发的时候要避免用反射。那么什么时候该用反射,什么时候不用反射呢?用什么方式来避免反射呢?如果不明白什么时候用反射,很难将反射活学活用了。
  二、分析
  当我们接到上面需求后,我长舒一口气,因为这回的需求还比较简单。
  我相信有人会说:“反射那几个api,一直没变过,你不会自己去查啊,觉得麻烦别写代码啊,不知道反射的内部细节你怎么去提高呢?”
  其实不然,重复写麻烦的代码和提高自己的代码能力是完全无关的,我实在不知道我们写了成千上万行的findViewById后除了知道类要和xml文件绑定外,还学到了什么。
  那么这回我们继续来挑战传统思维和模板式代码,来看看新一代的反射代码应该怎么写,如何用一行代码来反射出类。
  在做之前,来看看我们一般用反射来干嘛?
  1. 反射构建出无法直接访问的类
  2. set或get到无法访问的类变量
  3. 调用不可访问的方法
  三、解决方案
  3.1 一行代码写反射
  作为一个Android程序员,索性拿TextView这个类开刀吧。首先定义一个类变量:
  TextView mTv;
  通过反射得到实例:
  // 有参数,建立类
  mTv = Reflect.on(TextView.class).create(this).get();
  // 通过类全名得到类
  String word = Reflect.on("java.lang.String").create("Reflect TextView").get();
  // 无参数,建立类
  Fragment fragment = Reflect.on(Fragment.class).create().get();
  通过反射调用方法:
  // 调用无参数方法
  L.d("call getText() : " + Reflect.on(mTv).call("getText").toString());
  // 调用有参数方法
  Reflect.on(mTv).call("setTextColor", 0xffff0000);
  通过反射get、set类变量
  TextView中有个mText变量,来看看我们怎么接近它。
  // 设置参数
  Reflect.on(mTv).set("mText", "---------- new Reflect TextView ----------");
  // 获得参数
  L.d("setgetParam is " + Reflect.on(mTv).get("mText"));