反射(reflect)作为java最重要的一种机制,相信大家一定都很熟悉了,今天要介绍另一种和反射机制类似的方法调用机制——methodhandle。
methodhandle是java7引入的一种机制,主要是为了jvm支持动态语言。
一个methodhandle调用示例首先,让指北君给大家演示一下最基本的methodhandle使用。
第一步:创建查找对象:lookup// 获取look用于查找方法句柄 methodhandles.lookup lookup = methodhandles.lookup();第二步:创建方法类型:methodtype构造方法的返回值类型,参数类型
// 方法类型,描述返回值和参数,第一个参数为返回值类型,void则为void.class。第二个参数开始为被调用方法的参数类型 methodtype mt = methodtype.methodtype(boolean.class, string.class, int.class);第三步:查找方法句柄lookup的findvirtual查找成员方法
//查找方法句柄,参数1:调用类,参数2:方法名,参数3:方法类型 methodhandle handle = lookup.findvirtual(string.class, startswith, mt);第四步:方法调用通过mehodhandle的invoke方法执行,并返回结果
//方法调用,参数1:实例,参数2..n:方法参数 boolean value = (boolean)handle.invoke(the i am in the room, the, 0);以上就是一个简单的调用示例。
核心代码解读上面我们展示了一个最进本methodhandle方式的方法调用,下面我们将对其中用到的主要类进行介绍。这些主要的类包含methodtype,methodhandle,methodhandles及lookup。
methodtype首先,我们来看看methodtype,methodtype是用来封装方法输入输出类型的,包含方法的返回和方法的参数。methodtype构造方法为私有,只能通过methodtype提供的静态工具方法来获取实例
/** * constructor that performs no copying or validation. * should only be called from the factory method makeimpl */ private methodtype(class rtype, class[] ptypes) { this.rtype = rtype; this.ptypes = ptypes; }methodtype中常用的工具方法有:
大于一个参数public static methodtype methodtype(class rtype, class ptype0, class... ptypes) { class[] ptypes1 = new class[1+ptypes.length]; ptypes1[0] = ptype0; system.arraycopy(ptypes, 0, ptypes1, 1, ptypes.length); return makeimpl(rtype, ptypes1, true); }无参数public static methodtype methodtype(class rtype) { return makeimpl(rtype, no_ptypes, true); }工具方法都通过makeimple方法来封装methodtype实例,指北君带领大家来看看makeimple中做了哪些事情:
参数检查 返回值的类型不能为null,如果无返回使用void.class参数类型不能为null,且不能为void.class使用缓存表缓存methodtype实例,优化处理如果非信任模式(trusted==false),则克隆参数数组这里需要注意methodtype重写了hashcode方法,从逻辑看参数数组克隆不影响同类型的缓存机制。
static methodtype makeimpl(class rtype, class[] ptypes, boolean trusted) { if (ptypes.length == 0) { ptypes = no_ptypes; trusted = true; } methodtype primordialmt = new methodtype(rtype, ptypes); methodtype mt = interntable.get(primordialmt); if (mt != null) return mt; // promote the object to the real thing, and reprobe methodtype.checkrtype(rtype); if (trusted) { methodtype.checkptypes(ptypes); mt = primordialmt; } else { // make defensive copy then validate ptypes = arrays.copyof(ptypes, ptypes.length); methodtype.checkptypes(ptypes); mt = new methodtype(rtype, ptypes); } mt.form = methodtypeform.findform(mt); return interntable.add(mt); }除了静态工具方法外,methodtype还有几个实例方法,主要为差异性较小的methodtype提供快速获取实例的方法。包含:
changeparametertypeinsertparametertypesappendparametertypesdropparametertypesmethodhandlemethodhandle为抽象类,但是里面提供了大量的原生方法,提供底层访问,也是方法调用的核心逻辑。这部分涉及methodhandle的机制实现,对于使用功能来说指北君就不在此展开了。
@hotspotintrinsiccandidate public final native @polymorphicsignature object invokeexact(object... args) throws throwable; @hotspotintrinsiccandidate public final native @polymorphicsignature object invoke(object... args) throws throwable;
调用方法
methodhandles, lookupmethodhandles不是methodhandle的实现,他提供工具用于帮助获取methodhandle,我们主要使用到lookup(),publiclookup()
@callersensitive注解,可以使reflection.getcallerclass()获取到调用lookup()方法的类
@callersensitive @forceinline // to ensure reflection.getcallerclass optimization public static lookup lookup() { return new lookup(reflection.getcallerclass()); }public static lookup publiclookup() { return lookup.public_lookup; }lookup构造方法主要传入两个参数:
lookupclass搜寻的类,allowedmodes:许可模式。最后,通过lookup的findxxx获取到methodhandle,详细说明见下表:
查找方法
小结关于methodhandle的基本使用就基本讲完,这里附上一张类图便大家理解:
全球面板业产能过剩渐显 韩国和台湾地区“三足鼎立”的竞争将会更加白热化
关于Docker的一些基础操作有哪些
无人驾驶汽车将大量在上海行驶 年内投两千辆
有线防盗与无线防盗的区别,各自应用的优缺点分析
亚马逊万亿美元市值高不高?还能再涨27%
MethodHandle调用示例
常见的几种Modbus网关介绍
modbus 如何读取浮点数
什么是电池材料隔膜剂?
搭建做交易所平台开发币币OTC系统软件公司
小窗法屏蔽效能测试箱在屏蔽效能测试中的应用
LED发光二极管的检测简述
音响工程8大常见问题的检修
linux恢复远端备份文件
热点 | 荣耀正式发布新品类产品——“智慧屏”
智能网联汽车确定通信频段,车路协同开始火爆
四款可视化工具的优缺点
vivoXplay7新机曝光:全面屏+前后双摄,领先苹果三星的屏下指纹识别,vivoxplay7必将大火?
嵌入式工控机在物流领域有着怎样的应用
音频线的接法