MethodHandle(方法句柄)系列之二:方法句柄的简单使用
/**
*
* @author LiuYeFeng<897908343@qq.com>
* @date 2015年4月8日 下午10:41:13
* @CopyRight 2015 TopView Inc
* @version V1.0
*/
public class MethodHandleTest { public MethodHandle getHandler() {
MethodHandle mh = null;
MethodType mt = MethodType.methodType(String.class, int.class, int.class);
MethodHandles.Lookup lk = MethodHandles.lookup(); try {
mh = lk.findVirtual(String.class, "substring", mt);
} catch (Throwable e) {
e.printStackTrace();
} return mh;
} public static void main(String[] args) throws Throwable {
MethodHandle mh = new MethodHandleTest().getHandler();
String str = "hello world"; Object result1 = mh.invoke(str, , );
Object result2 = (String) mh.invokeExact(str, , );
// Object result2 = mh.invokeExact(str, new Integer(1), 3);
/**
* 上面这句方法执行时报错,因为方法类型为String.class, int.class, int.class
* 而返回的类型为Object,与声明中为String不符合
* 其中第二个参数类型为Integer,与声明中为int不符合,则类型适配不符合,系统报错。
*/ System.out.println("result 1:" + result1);
System.out.println("result 1:" + result2);
}
}
MethodType mt = MethodType.methodType(String.class, int.class, int.class)。 其次,获取方法句柄要用到Lookup对象,比如代码中的MethodHandles.Lookup lk,这个对象可以提供其所在环境中任何可见方法的方法句柄。我们可以将其比喻成包含有某个类对象的方法成员、方法的容器,通过lk.findVirtual(String.class, "substring", mt);具体锁定String类型中的某个方法,作为方法句柄返回。要从lookup对象中得到方法句柄,需要给出持有所需方法的类,方法的名称,以及跟方法相匹配的方法类型。 最后,获取到方法句柄后,我们就可以通过方法句柄来调用底层的方法,这点上,跟反射中的方法调用类似。方法句柄提供两个方法调用底层方法,invoke和invokeExact方法。invokeExact方法与直接调用底层方法是一样的,比如代码中,mh.invoke(str, 1, 2)就相当于直接调用str.substring(1, 3);具体两个方法的区别下面再说。这里先解析一下这两个方法的调用,方法的调用参数基本都一样,第一个参数为方法的接受对象,即是哪个对象执行这个方法,接下来的参数就是执行方法所需要的参数。当然第一个参数,也就是方法的接受对象,可以通过方法句柄的bindto动态的参数绑定方法来绑定,从而使方法句柄的调用和普通方法调用没区别,动态的参数绑定我们以后再研究。 这里需要强调一下,静态方法和动态方法之间的差别,静态方法是不需要制定方法的接受对象的,而一般方法是需要的。 参考资料:《java程序员修炼之道》、《深入理解java7核心技术与最佳实践》MethodHandle(方法句柄)系列之二:方法句柄的简单使用的更多相关文章
- SequoiaDB 系列之二 :SequoiaDB的简单CRUD操作
上一篇通过一系列的操作,终于把SequoiaDB的集群部署到单台机器上了. 建议去安装体验一下吧. 在整个环境的部署的体验来看,并没有MongoDB的部署简单,但是比MongoDB的部署要清晰.Mon ...
- 初识Redis系列之二:安装及简单使用
仅介绍windows下的安装 一:下载地址:https://github.com/MSOpenTech/redis/releases. Redis 支持 32 位和 64 位.这个需要根据你系统平台的 ...
- Java 设计模式系列(二)简单工厂模式和工厂方法模式
Java 设计模式系列(二)简单工厂模式和工厂方法模式 实现了创建者和调用者的分离.分为:简单工厂模式.工厂方法模式.抽象工厂模式 简单工厂模式.工厂方法模式都很简单,就不详细介绍了. 一.简单工厂 ...
- .Net中的AOP系列之《方法执行前后——边界切面》
返回<.Net中的AOP>系列学习总目录 本篇目录 边界切面 PostSharp方法边界 方法边界 VS 方法拦截 ASP.NET HttpModule边界 真实案例--检查是否为移动端用 ...
- Dagger2系列之使用方法
本系列只讲使用方法和使用中遇到的问题,如果还对dagger2还不了解的童鞋儿可以参考文章: http://www.jianshu.com/p/cd2c1c9f68d4 http://www.jians ...
- 电容值E系列标称方法
本节首先介绍常用的E系列标称方法,然后介绍电阻.电容器.电感器.二极管的分类.性能和识别方法,以及简单的实用电路. 一.E系列标称方法 厂家生产的电阻器,并不是包含任何阻值,就像人民币,只有1.2.5 ...
- MVC学习系列4--@helper辅助方法和用户自定义HTML方法
在HTML Helper,帮助类的帮助下,我们可以动态的创建HTML控件.HTML帮助类是在视图中,用来呈现HTML内容的.HTML帮助类是一个方法,它返回的是string类型的值. HTML帮助类, ...
- Java学习-026-类名或方法名应用之二 -- 统计分析基础
前文讲述了类名或方法的应用之一调试源码,具体请参阅:Java学习-025-类名或方法名应用之一 -- 调试源码 此文主要讲述类名或方法应用之二统计分析,通过在各个方法中插桩(调用桩方法),获取方法的调 ...
- 在keil 4中添加stc系列芯片的方法--【sky原创】
在keil 4中添加stc系列芯片的方法: 1.从官网下载uv3.cdb的文件网址是:http://www.stcmcu.com/ 2.下载好后把uv3.cdb文件改成STC.cdb:3. 然后将[S ...
随机推荐
- struts2初始化探索(一)
上篇文章已经介绍了struts2的简单使用,现在开始源码的学习. 本篇主要介绍struts2的初始化.对应的源码为StrutsPrepareAndExecuteFilter中的init方法. 先贴源码 ...
- python语法学习第六天--集合
集合(set)是一个无序的不重复元素序列. 可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典. 创建格 ...
- 一文讲透Cluster API的前世、今生与未来
作者:Luke Addison 原文链接:https://blog.jetstack.io/blog/cluster-api-past-present-and-future/ Cluster API是 ...
- HttpServletRequest与HttpServletResponse
一. 简介:每当客户端给Web服务器发送一个http请求,web服务器就会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象.request和respons ...
- 详解vue生命周期及每个阶段适合进行的操作
VUE生命周期的四个阶段 create 创建 -------- 创建vue实例并初始化 mount 挂载 -------- 把vue实例和视图进行关联 update 更新 ------- 监听数据与视 ...
- Puppeteer笔记(一):Puppeteer简介
一.Puppeteer简介 Puppeteer是NPM库,它提供了NodeJS高级API来控制Chrome.Puppeteer 默认以无头(无界面)方式运行,但也可以配置为运行有界面的Chrome. ...
- 让SpringBoot自动化配置不再神秘
本文若有任何纰漏.错误,还请不吝指出! 注:本文提到的Spring容器或者Bean容器,或者Spring Bean容器,都是指同一个事情,那就是代指BeanFactory.关于BeanFactory, ...
- 浅析String、StringBuilder、StringBuffer
谈谈我对 String.StringBuilder.StringBuffer 的理解 StringBuilder.StringBuffer 和 String 一样,都是用于存储字符串的. 1.那既然有 ...
- Poj2109 (2) k^n = p.
二分法,由p最大值最小值的中间值开始猜k,通过比较pow(k,n)与p的大小来进一步精确k,直到找到. #include<stdio.h> #include<math.h> # ...
- python list 与 String 互相转换
str0 = '127.0.0.1' list0 = str0.split('.') print(list0) #['127', '0', '0', '1'] str1 = '#'.join(list ...