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

  • 相关阅读:
    linux 查看 服务 命令
    Java Swing中键盘事件的处理(转)
    VI常用命令及快捷键(转)
    Linux source用法(转)
    无线桥接 WDS 中继(转)
    在远程桌面连接中使用任务管理器(转)
    linux 运行 级别(转)
    linux 当前用户 命令 w who(转)
    vecket适合和不适合的10种人(转)
    在查找预编译头使用时跳过解决(转)
  • 原文地址:https://www.cnblogs.com/Mrfanl/p/10544251.html
Copyright © 2011-2022 走看看