美文网首页
你所不知道的MethodHandle

你所不知道的MethodHandle

作者: Android笨鸟之旅 | 来源:发表于2018-10-23 09:50 被阅读0次

Method Handles

Method Hanldes是在Java 7引入的概念。全限定名是java.lang.invoke.MethodHandles。在这篇文章中,我们将学会如何创建,使用MethodHandles及它的原理。

1.介绍

Method Handles的引入是为了与已经存在的java.lang.reflect API相配合。他们分别是为了解决不同的问题而出现的。从性能角度上说,MethodHandle api要比反射快很多因为访问检查在创建的时候就已经完成了,而不是像反射一样等到运行时候才检查。但同时,Method Handles比反射更难用,因为没有列举类中成员,获取属性访问标志之类的机制。
另外,MethodHandles可以操作方法,更改方法参数的类型和他们的顺序。而反射则没有这些功能。
从以上角度看,反射更通用,但是安全性更差,因为可以在不授权的情况下使用反射对象。而method Handles遵从了分享者的能力。所以method handle是一种更低级的发现,适配和调用方法的方式,唯一的优点就是更快。所以反射更适合主流Java开发者,而method handle更适用于对编译和运行性能有要求的人。

2.使用

1.要使用method handle,首先需要得到Lookup。这是创造方法,构造函数,属性的method handles的工厂类。

// public方法的Lookup
MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
// 所有方法的Lookup
MethodHandles.Lookup lookup = MethodHandles.lookup();

2.要创建MethodHandle,lookup需要一个定义了它的类型的MethodType对象。这里的类型包括了传入参数的类型,和最后返回的类型,要一一对应。第一个是返回类型,如果没有返回值就是Void.class, 后面是可变的传入参数的类型。

a MethodType represents the arguments and return type accepted and returned by a method handle or passed and expected by a method handle caller.

例如

// 接收数组,返回一个List对象
MethodType mt = MethodType.methodType(List.class, Object[].class);

3.查找MethodHandle
Lookup之所以叫Lookup自然是因为他们有查找MethodHandle的能力。先看看他的方法。


image.png

4.接下来就可以进行查找并调用了

MethodType mt = MethodType.methodType(String.class, char.class, char.class);
MethodHandle replaceMH = publicLookup.findVirtual(String.class, "replace", mt);
 
String output = (String) replaceMH.invoke("jovo", Character.valueOf('o'), 'a');

5.方法调用细则:
有三种方法可以调用方法invoke(), invokeWithArugments()和invokeExact(),当我们使用invoke时,我们必须固定arguments的数目。

// invoke使用
MethodType mt = MethodType.methodType(String.class, char.class, char.class);
MethodHandle replaceMH = publicLookup.findVirtual(String.class, "replace", mt);
String output = (String) replaceMH.invoke("jovo", Character.valueOf('o'), 'a');

// invokeWithArguments使用
MethodType mt = MethodType.methodType(List.class, Object[].class);
MethodHandle asList = publicLookup.findStatic(Arrays.class, "asList", mt);
List<Integer> list = (List<Integer>) asList.invokeWithArguments(1,2);

// invokeExact
MethodType mt = MethodType.methodType(int.class, int.class, int.class);
MethodHandle sumMH = lookup.findStatic(Integer.class, "sum", mt);
int sum = (int) sumMH.invokeExact(1, 11);

具体的区别是:

与invokeExact方法不同,invoke方法允许更加松散的调用方式。它会尝试在调用的时候进行返回值和参数类型的转换工作。这是通过MethodHandle类的asType方法来完成的,asType方法的作用是把当前方法句柄适配到新的MethodType上面,并产生一个新的方法句柄。当方法句柄在调用时的类型与其声明的类型完全一致的时候,调用invoke方法等于调用invokeExact方法;否则,invoke方法会先调用asType方法来尝试适配到调用时的类型。如果适配成功,则可以继续调用。否则会抛出相关的异常。这种灵活的适配机制,使invoke方法成为在绝大多数情况下都应该使用的方法句柄调用方式。

参考:
https://www.baeldung.com/java-method-handles
https://www.cnblogs.com/night-wind/p/4405564.html

相关文章

  • 你所不知道的MethodHandle

    Method Handles Method Hanldes是在Java 7引入的概念。全限定名是java.lang...

  • MethodHandle

    Method Handles Method Hanldes是在Java 7引入的概念。全限定名是java.lang...

  • MethodHandle

    声明:本文是基于Java8的Api来进行叙述的,Java8之后添加的内容将不会涉及。不足之处,望不吝指点 一、Me...

  • MethodHandle详解

    从《Java虚拟机规范》中invokedynamic的描述可知invokedynamic的底层实现是基于java....

  • 虚拟机字节码执行引擎【动态类型语言支持(三)】

    invokedynamic指令 invokedynamic指令与MethodHandle机制的作用是一样的,都是为...

  • 2.MethodHandle

    Java7为间接调用方法引入了新的API。其中的关键是java.lang.invoke包,即方法句柄。你可以把它看...

  • MethodHandle源码阅读

    概述 在阅读技术文章时,经常听到MethodHandle的速度比反射快,这次准备彻底的了解下其实现原理 代码样例 ...

  • 你所不知道的

    黑夜里 你正匆匆地走着 天挺热 焦躁顺着热气 便溜出来了 视线模糊了 没有独特的聚焦点 朦胧的夜色 顺着心情 便溜...

  • 你所不知道的

    你所不知道的 游子方2017.9.19 静悄悄的我来了,正如你静悄悄的准备走。 不知何时我注意到了你。也不知何时,...

  • 你所不知道的

    明月街的街尾 一家破旧的店门口 有一盏忽明忽暗的老灯 它轻轻的挂在门口 偶尔它会随风轻轻的动一下 发出细微的声响 ...

网友评论

      本文标题:你所不知道的MethodHandle

      本文链接:https://www.haomeiwen.com/subject/kusozftx.html