zoukankan      html  css  js  c++  java
  • 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,如下图

      其中需要注意的是invokeinvokeExact,前者在调用的时候可以进行返回值和参数的类型转换工作,而后者是精确匹配的。比如,在MethodType中指定的参数类型是int,如果你用invoke调用时指定的参数是Integer类型,方法调用是可以运行的,这是通过MethodHandle类的astype方法产生一个新的方法句柄。而如果用的是invokeExact则在运行时会报错。
      另外一个需要注意的是invokexxx的所有方法返回的是Object,调用时若有返回结果一般需进行强制类型转换。
      最后还有一点,如果调用的方法没有返回值,那么在MethodType的工厂方法中的返回值类型写为void.class

  • 相关阅读:
    AJAX获取服务器当前时间
    Struts2的入门实例
    Java 测试技术3 Struts框架驱动(StrutsTestCase)
    Java单元测试技术1
    软件测试自动化:自动化工厂
    MySQL优化原理
    fetch_array()与fetch_assoc()的用法
    sometimesever js中创建数组,并往数组里添加元素
    将三维数组中的同名的键拆分成三维数组的每个数组中包括原来不同的二维数组的键...
    php serialize讲解与json性能测试
  • 原文地址:https://www.cnblogs.com/Mrfanl/p/10544251.html
Copyright © 2011-2022 走看看