在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. C# WinForm获取 当前执行程序路径的几种方法(转)

    1.获取和设置当前目录的完全限定路径. string str = System.Environment.CurrentDirectory; Result: C:xxxxxx 2.获取启动了应用程序的可 ...

  2. LeetCode_205. Isomorphic Strings

    205. Isomorphic Strings Easy Given two strings s and t, determine if they are isomorphic. Two string ...

  3. curl命令测试网络请求中DNS解析、响应时间

    https://blog.csdn.net/dreamer2020/article/details/78152576

  4. C++标准模板库STL算法与自适应容器(栈和队列)

    参考<21天学通C++>第23与第24章节,对STL算法与自适应容器进行介绍. 实际上在前面的STL顺序容器.关联容器进行介绍时或多或少引用到了一些STL算法中的模板函数.而自适应容器是在 ...

  5. mysql 排除系统库的全部备份

    前言: 有些时候,我们要对数据库进行备份的时候,由于GTID的缘故,导出系统库后,再次导入其他环境的数据库时,就会出问题.所以,我们需要排掉一些系统库,排除GTID对于数据库迁移的影响.   方法: ...

  6. os删除文件或者文件夹

    最近在使用os.remove删除目录时报错了,这里记录下os操作文件或者目录的常用方法 递归删除文件或文件夹 import shutil shutil.rmtree() 文件的重命名 os.renam ...

  7. poj1056(字符串判断是否存在一个字符串是另一个字符串的前缀)

    题目链接:https://vjudge.net/problem/POJ-1056 题意:给定一个字符串集,判断是否存在一个字符串是另一个字符串的前缀. 思路:和hdoj1671一样,有两种情况: 当前 ...

  8. [CF9D]How Many Trees?_动态规划_树形dp_ntt

    How many trees? 题目链接:https://www.codeforces.com/contest/9/problem/D 数据范围:略. 题解: 水题. $f_{i,j}$表示$i$个节 ...

  9. numpy 数组集合运算及下标操作

    1. 数组的集合运算 1.1. 并集 np.union1d(a,b)计算数组的并集: In [1]: import numpy as np In [2]: a = np.array([1,2,3]) ...

  10. java实现邮箱发送邮件功能

    邮箱验证是一个很常见的功能了,基本上每个网站都会用的到,java也有专门的jar来处理邮件发送等服务,这里只是简单的实现一下发送邮件的功能,具体jar包就不再提供了,我会把所有需要引用的包都贴出来,方 ...