java的MethodHandle类详解
一.总述
java7为间接调用方法提供了MethodHandle类,即方法句柄。可以将其看作是反射的另一种方式。
这是使用MethodHandle调用方法的一个例子:
public class Test {
public static void main(String[] args) throws Throwable {
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType mt = MethodType.methodType(String.class,char.class,char.class);
try {
MethodHandle mh = lookup.findVirtual(String.class,"replace", mt);
String handled_str = (String) mh.invoke("abc",'a','c');
System.out.print(handled_str);
} catch (NoSuchMethodException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
用MethodHandle调用方法的流程为:
- (1) 创建MethodType,获取指定方法的签名
- (2) 在Lookup中查找MethodType的方法句柄MethodHandle
- (3) 传入方法参数通过MethodHandle调用方法
二.MethodType
MethodType表示一个方法类型的对象,每个MethodHandle都有一个MethodType实例,MethodType用来指明方法的返回类型和参数类型。其有多个工厂方法的重载。
static MethodType methodType(Class<?> rtype)
static MethodType methodType(Class<?> rtype, Class<?> ptype0)
static MethodType methodType(Class<?> rtype, Class<?>[] ptypes)
static MethodType methodType(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes)
static MethodType methodType(Class<?> rtype, List<Class<?>> ptypes)
static MethodType methodType(Class<?> rtype, MethodType ptypes)
如上面示例代码中的
MethodType mt = MethodType.methodType(String.class,char.class,char.class);就得到了一个方法的参数类型为char,char,返回类型为String的MethodType。
三.Lookup
MethodHandle.Lookup可以通过相应的findxxx方法得到相应的MethodHandle,相当于MethodHandle的工厂方法。查找对象上的工厂方法对应于方法、构造函数和字段的所有主要用例。下面是官方API文档对findxxx的说明,这些工厂方法和结果方法处理的行为之间的对应关系:

可以看出findStatic相当于得到的是一个static方法的句柄,findVirtual找的是普通方法。其他的可以从官方文档中阅读得知,这里不详细说明了。
四. MethodHandle
MethodHandle是什么?简单的说就是方法句柄,通过这个句柄可以调用相应的方法。官方文档对其的解释为:
“ A method handle is a typed, directly executable reference to an underlying method, constructor, field, or similar low-level operation, with optional transformations of arguments or return values. These transformations are quite general, and include such patterns as conversion, insertion, deletion, and substitution.”
翻译如下:
方法句柄是对底层方法、构造函数、字段或类似低级操作的类型化、直接可执行的引用,具有参数或返回值的可选转换。这些转换非常普遍,包括转换、插入、删除和替换等模式
常用的方法为invokexxx,如下图

其中需要注意的是invoke和invokeExact,前者在调用的时候可以进行返回值和参数的类型转换工作,而后者是精确匹配的。比如,在MethodType中指定的参数类型是int,如果你用invoke调用时指定的参数是Integer类型,方法调用是可以运行的,这是通过MethodHandle类的astype方法产生一个新的方法句柄。而如果用的是invokeExact则在运行时会报错。
另外一个需要注意的是invokexxx的所有方法返回的是Object,调用时若有返回结果一般需进行强制类型转换。
最后还有一点,如果调用的方法没有返回值,那么在MethodType的工厂方法中的返回值类型写为void.class
java的MethodHandle类详解的更多相关文章
- java之StringBuffer类详解
StringBuffer 线程安全的可变字符序列. StringBuffer源码分析(JDK1.6): public final class StringBuffer extends Abstract ...
- java之AbstractStringBuilder类详解
目录 AbstractStringBuilder类 字段 构造器 方法 public abstract String toString() 扩充容量 void expandCapacity(in ...
- java之StringBuilder类详解
StringBuilder 非线程安全的可变字符序列 .该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍).如果可能,建议优先采用该类,因为在 ...
- java.lang.Thread类详解
java.lang.Thread类详解 一.前言 位于java.lang包下的Thread类是非常重要的线程类,它实现了Runnable接口,今天我们来学习一下Thread类,在学习Thread类之前 ...
- Java中dimension类详解
Java中dimension类详解 https://blog.csdn.net/hrw1234567890/article/details/81217788
- java之Matcher类详解
在JDK 1.4中,Java增加了对正则表达式的支持. java与正则相关的工具主要在java.util.regex包中:此包中主要有两个类:Pattern.Matcher. Matcher 声明: ...
- java的ReentrantLock类详解
ReentrantLock 能用于更精细化的加锁的Java类, 通过它能更清楚了解Java的锁机制 ReentrantLock 类的集成关系有点复杂, 既有内部类, 还有多重继承关系 类的定义 pub ...
- Java的String类详解
Java的String类 String类是除了Java的基本类型之外用的最多的类, 甚至用的比基本类型还多. 同样jdk中对Java类也有很多的优化 类的定义 public final class S ...
- Java Properties工具类详解
1.Java Properties工具类位于java.util.Properties,该工具类的使用极其简单方便.首先该类是继承自 Hashtable<Object,Object> 这就奠 ...
随机推荐
- sql拼接字符串
update boc_loan_apply set birthday=concat(birthday,'-01');
- Display PDF in browser | Acrobat, Reader XI
点这个链接查看详细的解决办法 http://helpx.adobe.com/acrobat/using/display-pdf-browser-acrobat-xi.html When you cli ...
- JavaScript 对象属性作实参以及实参对象的callee属性
参考自<<JavaScript权威指南 第6版>> /* * 将对象属性用作实参, 从而不必记住参数的顺序. */ function arraycopy(from,from_s ...
- Text Relatives
[Text Relatives] With TextKit the resources at your disposal range from framework objects—such as te ...
- 电商商品规则属性sku 工具类
/** * 商品模块: * 使用:var SKU = sku.init({ id:'sku', item: item, data:data }); * @config item = [{"i ...
- SpringBoot2.0WebFlux响应式编程知识总结
- ZOJ2748 Free Kick 2017-04-18 20:40 40人阅读 评论(0) 收藏
Free Kick Time Limit: 2 Seconds Memory Limit: 65536 KB In a soccer game, a direct free kick is ...
- HDU2544 最短路 2017-04-12 18:51 31人阅读 评论(0) 收藏
最短路 Time Limit : 5000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Submissio ...
- [label][Smarty]Smarty使用心得
Smarty模板引擎,使用smarty好处就是可以实现页面缓存,从而加快了初始化之后的页面访问速度. 某种程度上,smarty模板确保了template页面的代码整洁,避免了HTML标记与PHP的混合 ...
- delphi 拆分字符串
最近在使用Delphi开发一种应用系统的集成开发环境.其中需要实现一个字符串拆分功能,方法基本原型应该是:procedure SplitString(src: string ; ch: Char; v ...