网站首页 > 技术文章 正文
在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”或“架构资料”有惊喜!加关注,持续更新!!!
- 上一篇: 2020年突发环境事件应急预案备案公示名单
 - 下一篇: 祝贺!18家种企获批生产经营许可证
 
猜你喜欢
- 2024-09-09 分享一些你可能还没使用的 JavaScript 技巧
 - 2024-09-09 可视化搜索引擎和机器学习技术索引Python实例
 - 2024-09-09 Python 爬取张国荣最火的 8 首歌,60000 评论看完泪奔!
 - 2024-09-09 万字详文:超越 BERT 模型的 ELECTRA 代码解读
 - 2024-09-09 大受欢迎的Kubernetes:快速入门&进阶实战
 - 2024-09-09 首发|Clusterpedia 0.1.0 四大重要功能
 - 2024-09-09 NET开发者的HTTP交互新宠(豪门36夜:黑帝的替身新宠)
 - 2024-09-09 BGP路径属性:Origin和AS_PATH(bgp路由协议中origin属性)
 - 2024-09-09 如何修改容器时间而不改变宿主机时间?
 - 2024-09-09 VASP计算杂化能带详细步骤教程(vasp杂化泛函计算)
 
- 最近发表
 - 
- 聊一下 gRPC 的 C++ 异步编程_grpc 异步流模式
 - [原创首发]安全日志管理中心实战(3)——开源NIDS之suricata部署
 - 超详细手把手搭建在ubuntu系统的FFmpeg环境
 - Nginx运维之路(Docker多段构建新版本并增加第三方模
 - 92.1K小星星,一款开源免费的远程桌面,让你告别付费远程控制!
 - Go 人脸识别教程_piwigo人脸识别
 - 安卓手机安装Termux——搭建移动服务器
 - ubuntu 安装开发环境(c/c++ 15)_ubuntu安装c++编译器
 - Rust开发环境搭建指南:从安装到镜像配置的零坑实践
 - Windows系统安装VirtualBox构造本地Linux开发环境
 
 
- 标签列表
 - 
- cmd/c (90)
 - c++中::是什么意思 (84)
 - 标签用于 (71)
 - 主键只能有一个吗 (77)
 - c#console.writeline不显示 (95)
 - pythoncase语句 (88)
 - es6includes (74)
 - sqlset (76)
 - apt-getinstall-y (100)
 - node_modules怎么生成 (87)
 - chromepost (71)
 - flexdirection (73)
 - c++int转char (80)
 - mysqlany_value (79)
 - static函数和普通函数 (84)
 - el-date-picker开始日期早于结束日期 (76)
 - js判断是否是json字符串 (75)
 - c语言min函数头文件 (77)
 - asynccallback (87)
 - localstorage.removeitem (77)
 - vector线程安全吗 (73)
 - java (73)
 - js数组插入 (83)
 - mac安装java (72)
 - 无效的列索引 (74)
 
 
