java MethodHandle解析

来源:互联网 发布:mac安装软件 编辑:程序博客网 时间:2024/06/15 02:01

MethodHandle对应的就是一个方法的句柄,有些类似于java反射中的Method方法

1、那么如何获取到一个方法的MethodHandle句柄呢?

它使用的是MethodHandles.Lookupd对象来获取获取。Lookup包含以下常用方法:

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是该属性的名称,不是方法名称

从上面的方法中给定对应方法的class,方法名以及参数类型来查找某个方法对应的MethodHandle

2、参数类型使用的是MethodType类进行封装,因为参数类型包含返回类型以及形参类型,另外形参可能有多个。

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

static MethodType methodType(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes)

第一次参数是返回类型,后面的剩余参数是方法的参数类型

3、MethodHandles.Lookup对象的获取使用的是MethodHandle.Lookup()。

4、使用MethodHandle.invoke或者MethodHandle.invokeExact进行方法的调用。

public class MethodHandleTest {      public static void main(String[] args) throws Throwable {          MethodHandles.Lookup lookup = MethodHandles.lookup();          MethodHandle mh = lookup.findStatic(MethodHandleTest.class, "doubleVal", MethodType.methodType(int.class, int.class));          List<Integer> dataList = Arrays.asList(1, 2, 3, 4, 5);          MethodHandleTest.transform(dataList, mh);// 方法做为参数          for (Integer data : dataList) {              System.out.println(data);//2,4,6,8,10          }      }      public static List<Integer> transform(List<Integer> dataList, MethodHandle handle) throws Throwable {          for (int i = 0; i < dataList.size(); i++) {              dataList.set(i, (Integer) handle.invoke(dataList.get(i)));//invoke          }          return dataList;      }      public static int doubleVal(int val) {          return val * 2;      }  }