一.总述

  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类详解的更多相关文章

  1. java之StringBuffer类详解

    StringBuffer 线程安全的可变字符序列. StringBuffer源码分析(JDK1.6): public final class StringBuffer extends Abstract ...

  2. java之AbstractStringBuilder类详解

    目录 AbstractStringBuilder类 字段 构造器 方法   public abstract String toString() 扩充容量 void  expandCapacity(in ...

  3. java之StringBuilder类详解

    StringBuilder 非线程安全的可变字符序列 .该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍).如果可能,建议优先采用该类,因为在 ...

  4. java.lang.Thread类详解

    java.lang.Thread类详解 一.前言 位于java.lang包下的Thread类是非常重要的线程类,它实现了Runnable接口,今天我们来学习一下Thread类,在学习Thread类之前 ...

  5. Java中dimension类详解

    Java中dimension类详解 https://blog.csdn.net/hrw1234567890/article/details/81217788

  6. java之Matcher类详解

    在JDK 1.4中,Java增加了对正则表达式的支持. java与正则相关的工具主要在java.util.regex包中:此包中主要有两个类:Pattern.Matcher. Matcher  声明: ...

  7. java的ReentrantLock类详解

    ReentrantLock 能用于更精细化的加锁的Java类, 通过它能更清楚了解Java的锁机制 ReentrantLock 类的集成关系有点复杂, 既有内部类, 还有多重继承关系 类的定义 pub ...

  8. Java的String类详解

    Java的String类 String类是除了Java的基本类型之外用的最多的类, 甚至用的比基本类型还多. 同样jdk中对Java类也有很多的优化 类的定义 public final class S ...

  9. Java Properties工具类详解

    1.Java Properties工具类位于java.util.Properties,该工具类的使用极其简单方便.首先该类是继承自 Hashtable<Object,Object> 这就奠 ...

随机推荐

  1. [Training Video - 2] [Groovy Introduction]

    Building test suites, Test cases and Test steps in SOAP UI Levels : test step level test case level ...

  2. centos7安装kubernetes 1.1

    原文地址:http://foxhound.blog.51cto.com/1167932/1717105 前提:centos7 已经update yum update -y 一.创建yum源 maste ...

  3. csdn的博客上传word图片

    目前大部分的博客作者在用Word写博客这件事情上都会遇到以下3个痛点: 1.所有博客平台关闭了文档发布接口,用户无法使用Word,Windows Live Writer等工具来发布博客.使用Word写 ...

  4. 二)quartz.properties

    The Properties File Quartz uses a properties file called (kudos on the originality) quartz.propertie ...

  5. 从Objective-C到Swift,你必须会的(四)DLog

    调试的时候打断点太慢,所以输出log就是一个很好的选择了.断点,一行一行的按,太麻烦了.从log里一条一条的看,很快就可以找到到哪个函数的哪个地方这个代码就没执行了.这里不详细讨论调试技巧的事.不过大 ...

  6. Receiving Transaction Processor Conundrum

    what would we do if we are faced with a situation to execute a receiving transaction in oracle ebusi ...

  7. Android-开关机的广播

    在上一篇博客Android-sdcard广播的接收处理,中介绍了,如何订阅接收者,去接收系统发送的Sdcard状态改变广播,而这篇博客是订阅接收者,去接收开机/关机的广播 Android操作系统在开机 ...

  8. 在ASP.NET Core2上操作MongoDB就是能这么的简便酷爽(自动完成分库分表)

    NoSQL是泛指非关系型的数据库,现今在我们的项目中也多有使用,其独特的优点为我们的项目架构带来了不少亮点,而我们这里的主角(MongoDB)则是NoSQL数据库家族中的一种.事实上,NoSQL数据库 ...

  9. github的使用经历

    首先我打开百度搜索markdown,点击这个在线编辑器,开始编写,如下图: 预览效果如下: 然后打开github的网页登录后,点击下图这个标志: 然后给给要上传的一个命名: 然后选择README 确认 ...

  10. JQuery --- 第五期 (JQuery节点操作)

    学习笔记 1.JQuery添加节点相关方法 <!DOCTYPE html> <html lang="en"> <head> <meta c ...