在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可以对大家的开发日常有所帮助。

写在最后:欢迎留言讨论,加关注,持续更新!!!

一个让Java事半功倍的反射库的更多相关文章

  1. 我是怎么开发一个小型java在线学习网站的

    2016/1/27 11:55:14 我是怎么开发一个小型java在线学习网站的 一直想做一个自己的网站(非博客),但是又不知道做什么内容的好,又一次看到了w3schools,就萌发了开发一个在线ja ...

  2. 一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库 RxJava,相当好

    https://github.com/ReactiveX/RxJava https://github.com/ReactiveX/RxAndroid RX (Reactive Extensions,响 ...

  3. 如何用Maven创建一个普通Java项目

    一下内容包括:用Maven创建一个普通Java项目,并把该项目转成IDEA项目,导入到IDEA,最后把这个项目打包成一个jar文件. 有时候运行mvn命令失败,重复运行几次就OK了,无解(可能因为网络 ...

  4. BuguMongo是一个MongoDB Java开发框架,集成了DAO、Query、Lucene、GridFS等功能

    http://code.google.com/p/bugumongo/ 简介 BuguMongo是一个MongoDB Java开发框架,它的主要功能包括: 基于注解的对象-文档映射(Object-Do ...

  5. WEKA,一个开源java的数据挖掘工具

    开始研究WEKA,一个开源java的数据挖掘工具. HS沉寂这么多天,谁知道偏偏在我申请离职的时候给我安排了个任务,哎,无语. 于是,今天看了一天的Weka. 主要是看了HS提供的三个文章(E文,在g ...

  6. 输出多行字符的一个简单JAVA小程序

    public class JAVA { public static void main(String[] args) { System.out.println("-------------- ...

  7. JSpider是一个用Java实现的WebSpider

    JSpider是一个用Java实现的WebSpider,JSpider的执行格式如下: jspider [URL] [ConfigName] URL一定要加上协议名称,如:http://,否则会报错. ...

  8. Nutch 是一个开源Java 实现的搜索引擎

    Nutch 是一个开源Java 实现的搜索引擎.它提供了我们运行自己的搜索引擎所需的全部工具.包括全文搜索和Web爬虫. Nutch的创始人是Doug Cutting,他同时也是Lucene.Hado ...

  9. Java基础教程1:环境配置及第一个HelloWorld.java

    本文主要介绍JDK环境配置.Sublime Text3配置及第一个HelloWorld.Java程序.运行环境为Win10系统,使用JDK1.8版本. 1. JDK下载及环境配置 1.1 JDK下载 ...

随机推荐

  1. Qt编写气体安全管理系统6-地图监控

    一.前言 地图监控主要是提供一个地图(可以是平面的也可以是立体彩色的,一般建议鸟瞰图,有3D感),然后设备在对应的地图上,可以切换地图来查看对应区域的设备,一般来说一个区域会有一个地图文件,设备在地图 ...

  2. Oracle中Sequence使用

    Oracle提供了sequence对象,由系统提供自增长的序列号,通常用于生成数据库数据记录的自增长主键或序号的地方. 下面介绍一下关于sequence 的生成,修改,删除等常用的操作: 1. 创建 ...

  3. 123457123456#3#----com.ppGame.konglongPuzzle78--前拼后广--konglongPT游戏_pp

    com.ppGame.konglongPuzzle78--前拼后广--konglongPT游戏_pp

  4. 报错:Sqoop2 Error message: Class not found JDBC Driver Class: com.mysql.jdbc.Driver

    报错背景: CDH安装完成Sqoop2的组建后进行创建link的操作. 报错现象: There are issues with entered data, please revise your inp ...

  5. git 更新fork的远程仓库

    1.添加远程仓库到本地remote分支 git remote add upstream git@github.com:apache/flink.git # 远程仓库地址 2.查看当前仓库的远程分支 g ...

  6. php调用webservice报错Class 'SoapClient' not found(转)

    php在调用webservice时,报告如下类似错误: ( ! ) Fatal error: Class 'SoapClient' not found in E:/WebSrv/CI/system/l ...

  7. Spring4.X整合redis

    包和版本的依赖关系很严重 我的配置 spring-data-redis-1.6.6.RELEASE.jar spring-tx-4.2.5.RELEASE.jar redis-2.7.2.jar co ...

  8. HTML布局水平导航条2制作

    前两个博文导航条都不是铺满水平的浏览器的,很多导航条样式都是随着浏览器的移动,是100%.此外前两个博文导航条都是块状点击的,也就是给a标签加宽高,设置成块状显示,点击的时候不一定要点文字,只要点击该 ...

  9. 微信小程序常用控件汇总

    1.图片标签: <image src="/images/aaa.png"></image> 2.文本标签: <text>Hello</te ...

  10. 特征抽取: sklearn.feature_extraction.FeatureHasher

    sklearn.feature_extraction.FeatureHasher(n_features=1048576, input_type="dict", dtype=< ...