反射利器——jOOR

反射提供了运行时修改对象的能力,但Java提供的Refelec包实在是太复杂了,首先得到Class、再根据Class去找到Field或Method,再进行调用,虽然流程很固定,但写起来确实很冗长。有没有一种简单的工具可以方便快捷的实现反射调用呢? 答案是jOOR。 jOOR是一个非常简单方便的操作Class结构的API,支持链式调用,非常直观好理解。类库也很简单,一共就4个类。

使用

一个简单的例子

import static org.joor.Reflect.*;String world = on("java.lang.String")  // Like Class.forName()                .create("Hello World") // Call most specific matching constructor                .call("substring", 6)  // Call most specific matching substring() method                .call("toString")      // Call toString()                .get();                // Get the wrapped object, in this case a String

对于上面代码,有几点说明:

  • on()方法用于获取Class对象,可以传入String、Object、Class
  • create()方法等同于调用该Class对象的构造方法,即实例化一个对象,有有参和无参两种形式
  • call()方法等于调用某一方法,并将参数传入
  • get()用于获取最终的对象

改变字段

char[] newValue=new char[]{'H','e','l','l','o'};        String changed=on("java.lang.String")                .create("Hello World")                .set("value",newValue)                .call("toString")                .get();        System.out.println(changed);

改变字段很简单,使用set()方法即可,传入新的值即可了。

接口抽象

jOOR使用动态代理是一件很方便的事情,比如说:

public interface StringProxy {  String substring(int beginIndex);}String substring = on("java.lang.String")                    .create("Hello World")                    .as(StringProxy.class) // Create a proxy for the wrapped object                    .substring(6);         // Call a proxy method

as()方法将一个实例代理到某个接口,as()方法内部使用的就是动态代理的Proxy方案。

与Java原生的反射比较

以上面改变String字段的例子为例,如果使用原生方法,那么代码如下:

try{            String src="Hello World";            char[] newValue=new char[]{'H','e','l','l','o'};            Class clazz=src.getClass();            Field value_field=clazz.getDeclaredField("value");            value_field.setAccessible(true);            value_field.set(src,newValue);            System.out.println(src);        }catch (Exception e){            e.printStackTrace();        }

对比可以看到,jOOR是十分简单流利的

运行时编译Java代码

举个例子:

Supplier<String> supplier = Reflect.compile(    "com.example.HelloWorld",    "package com.example;\n" +    "class HelloWorld implements java.util.function.Supplier<String> {\n" +    "    public String get() {\n" +    "        return \"Hello World!\";\n" +    "    }\n" +    "}\n").create().get();// Prints "Hello World!"System.out.println(supplier.get());

总结

经过上面的介绍,是不是发现jOOR对于处理反射而言,确实很简单方便,赶紧用起来吧!!!

本文分享自微信公众号 - 每天学点Android知识(android_every_day),作者:星风coder

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-05-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 从0到1实现一个Android路由(3)——APT收集路由

    之前的例子中,关于url和Activity之间的关系,是写死在一个Map中的,可以看做是一个静态路由。随着项目规模的扩大,这样一个个的手写那张表是个工作量比较大...

    用户1108631
  • Flutter版本玩Android客户端(5)——微信公众号tab点击跳转

    在Flutter版本玩Android客户端(4)——知识体系tab点击跳转中,完成了主页面知识体系tab的点击跳转,本文主要完成微信公众号tab的跳转。效果如下...

    用户1108631
  • Flutter版本玩Android(2)——主页面数据获取

    上一部分构造了主页面,这一部分主要完成主页面三个tab的数据获取,下一步的点击事件目前都未处理。

    用户1108631
  • 微信公众号H5支付遇到的那些坑

    简史 官方文档说的很清楚,商户已有H5商城网站,用户通过消息或扫描二维码在微信内打开网页时,可以调用微信支付完成下单购买的流程。 当然,最近微信支付平台也加入了...

    小柒2012
  • java练习本(2019-07-06)

    String类型会指向堆内存中的存储空间,因此当通过==对String类型进行比较时,比较的是相应变量的地址。只要指向的是同一地址则两个String类型==比较...

    微笑的小小刀
  • 微信公众号H5支付遇到的那些坑

    官方文档说的很清楚,商户已有H5商城网站,用户通过消息或扫描二维码在微信内打开网页时,可以调用微信支付完成下单购买的流程。

    小柒2012
  • 关于SpringMVC中如何把查询数据全转成String类型

    上帝
  • 老板看了我的代码,直呼“666”,说涨工资!

    如何更规范化编写Java 代码的重要性想必毋需多言,其中最重要的几点当属提高代码性能、使代码远离Bug、令代码更优雅。

    程序员小强
  • java中两个map比较

    ydymz
  • 这样规范写代码,同事直呼“666”

    用户1516716

扫码关注云+社区

领取腾讯云代金券