MethodHandle

JDK7为间接调用方法引入新的API,在java.lang.invoke包下,可以看作为反射的升级版,但它不像反射API那样显得冗长、繁重

主要的类

MethodHandle

方法句柄、对可直接执行的方法的类型化引用,能够安全调用方法的对象。
MethodHandle 是抽象类,无法直接实例化,需通过MethodHandles.Lookup的工厂方法来创建

MethodType

每个方法句柄都有一个MethodType实例,用来指明方法的返回类型和参数类型。

  • static MethodType methodType(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes)
    第一次参数是返回类型,后面的剩余参数是方法的参数类型

MethodHandles

这个类只包含操作或返回方法句柄的静态方法。它们分为以下几类:

  • 查找方法,帮助创建方法和字段的方法句柄。
  • 组合方法,将先前的方法合并或转换成新的方法。
  • 其他工厂方法来创建方法来模拟其他常见的JVM操作或控制流模式

MethodHandles.Lookup

创建MethodHandle只想的工厂方法查找类

  • MethodHandle findVirtual(Class<?> refc, String name, MethodType type)查找方法名为name的方法
  • MethodHandle findStatic(Class<?> refc, String name, MethodType type)查找静态方法
  • MethodHandle findSetter(Class<?> refc, String name, Class<?> type)查找setter方法,name是该属性的名称,不是方法名称

使用示例

  • 获取String类的replace方法,并传参调用
    1
    2
    3
    4
    MethodHandles.Lookup lookup = MethodHandles.lookup();
    MethodType mt = MethodType.methodType(String.class, char.class, char.class);
    MethodHandle mh = lookup.findVirtual(String.class, "replace", mt);
    String s = (String) mh.invokeExact("daddy",'d','n');

参考资料

  • 《Java程序员修炼之道》
  • Java SE 8 API Documentation