一个让Java事半功倍的反射库
在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事半功倍的反射库的更多相关文章
- 我是怎么开发一个小型java在线学习网站的
2016/1/27 11:55:14 我是怎么开发一个小型java在线学习网站的 一直想做一个自己的网站(非博客),但是又不知道做什么内容的好,又一次看到了w3schools,就萌发了开发一个在线ja ...
- 一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库 RxJava,相当好
https://github.com/ReactiveX/RxJava https://github.com/ReactiveX/RxAndroid RX (Reactive Extensions,响 ...
- 如何用Maven创建一个普通Java项目
一下内容包括:用Maven创建一个普通Java项目,并把该项目转成IDEA项目,导入到IDEA,最后把这个项目打包成一个jar文件. 有时候运行mvn命令失败,重复运行几次就OK了,无解(可能因为网络 ...
- BuguMongo是一个MongoDB Java开发框架,集成了DAO、Query、Lucene、GridFS等功能
http://code.google.com/p/bugumongo/ 简介 BuguMongo是一个MongoDB Java开发框架,它的主要功能包括: 基于注解的对象-文档映射(Object-Do ...
- WEKA,一个开源java的数据挖掘工具
开始研究WEKA,一个开源java的数据挖掘工具. HS沉寂这么多天,谁知道偏偏在我申请离职的时候给我安排了个任务,哎,无语. 于是,今天看了一天的Weka. 主要是看了HS提供的三个文章(E文,在g ...
- 输出多行字符的一个简单JAVA小程序
public class JAVA { public static void main(String[] args) { System.out.println("-------------- ...
- JSpider是一个用Java实现的WebSpider
JSpider是一个用Java实现的WebSpider,JSpider的执行格式如下: jspider [URL] [ConfigName] URL一定要加上协议名称,如:http://,否则会报错. ...
- Nutch 是一个开源Java 实现的搜索引擎
Nutch 是一个开源Java 实现的搜索引擎.它提供了我们运行自己的搜索引擎所需的全部工具.包括全文搜索和Web爬虫. Nutch的创始人是Doug Cutting,他同时也是Lucene.Hado ...
- Java基础教程1:环境配置及第一个HelloWorld.java
本文主要介绍JDK环境配置.Sublime Text3配置及第一个HelloWorld.Java程序.运行环境为Win10系统,使用JDK1.8版本. 1. JDK下载及环境配置 1.1 JDK下载 ...
随机推荐
- C++的override和final
1.final用于让虚函数不可被重写 struct B2 { virtual void f() final {} // final 函数 }; struct D2 : B2 { virtual voi ...
- ABAP DEMO 下拉框
效果展示: *&---------------------------------------------------------------------* *& Report YCX ...
- 基于Broadcast 状态的Flink Etl Demo
接上文: [翻译]The Broadcast State Pattern(广播状态) 最近尝试了一下Flink 的 Broadcase 功能,在Etl,流表关联场景非常适用:一个流数据量大,一个流数据 ...
- 【JQuery】性能优化方法
尽管JavaScript比JAVA C++慢很多,JQuery比原生Js还慢很多,但是我们通过良好的编程习惯还是能提高代码执行的效率. 一.选择器的使用 选择同一个元素,各种方法之间的性能是不一样的, ...
- web端自动化——Python读取txt文件、csv文件、xml文件
1.读取txt文件 txt文件是我们经常操作的文件类型,Python提供了以下几种读取txt文件的方式. 1)read(): 读取整个文件. 2)readline(): 读取一行数据. 3)readl ...
- 什么时候该用readfile() , fread(), file_get_contents(), fgets()?
fread() 和 readfile() fread() 最大一次性能读取 8k长度的字节数,所以不能一次性读取大文件去作下载. 优势在于,操作更加灵活,每次读取指定字节的内容,用于下载时方便控制服务 ...
- ubuntu18.04 阿里镜像源
备份:cp /etc/apt/sources.list /etc/apt/sources.list.bak 清空source.list:echo > /etc/apt/sources.list ...
- es操作手册
0 _search查询数据时可以指定多个index和type GET /index1,index2/type1,type2/_search GET /_all/type1/_search 相当于查询全 ...
- Spring之27:BeanDefinitionRegistry
关于BeanDefinition见<Spring之Ⅰ:BeanDefinition> BeanDefinitionRegistry的类图: BeanDefinition 的注册接口,如 R ...
- WUSTOJ 1315: 杜学霸和谭女神(Java)
题目链接: