java MethodHandle解析
簡介
java7在JSR 292中增加了對動態型別語言的支援,使Java也可以像C語言那樣將方法作為引數傳遞,其實現在lava.lang.invoke包中。MethodHandle作用類似於反射中的Method類,但它比Method類要更加靈活和輕量級。通過MethodHandle進行方法呼叫一般需要以下幾步:
(1)建立MethodType物件,指定方法的簽名;
(2)在MethodHandles.Lookup中查詢型別為MethodType的MethodHandle;
(3)傳入方法引數並呼叫MethodHandle.invoke或者MethodHandle.invokeExact方法。
MethodType
可以通過MethodHandle類的type方法檢視其型別,返回值是MethodType類的物件。也可以在得到MethodType物件之後,呼叫MethodHandle.asType(mt)方法適配得到MethodHandle物件。可以通過呼叫MethodType的靜態方法建立MethodType例項,有三種建立方式:
(1)methodType及其過載方法:需要指定返回值型別以及0到多個引數;
(2)genericMethodType:需要指定引數的個數,型別都為Object;
(3)fromMethodDescriptorString:通過方法描述來建立。
建立好MethodType物件後,還可以對其進行修改,MethodType類中提供了一系列的修改方法,比如:changeParameterType、changeReturnType等。
Lookup
MethodHandle.Lookup相當於MethodHandle工廠類,通過findxxx方法可以得到相應的MethodHandle,還可以配合反射API建立MethodHandle,對應的方法有unreflect、unreflectSpecial等。
invoke
在得到MethodHandle後就可以進行方法呼叫了,有三種呼叫形式:
(1)invokeExact:呼叫此方法與直接呼叫底層方法一樣,需要做到引數型別精確匹配;
(2)invoke:引數型別鬆散匹配,通過asType自動適配;
(3)invokeWithArguments:直接通過方法引數來呼叫。其實現是先通過genericMethodType方法得到MethodType,再通過MethodHandle的asType轉換後得到一個新的MethodHandle,最後通過新MethodHandle的invokeExact方法來完成呼叫。
附MethodHandle作為引數的示例程式碼:
package com.sun.jojo.methodhandle;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.Arrays;
import java.util.List;
/**
* Author sunjiamin
* Date 2017/8/9 11:14
* Describe :
*/
public class MethodHandleTest {
public static void main(String[] args) throws Throwable {
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle methodHandle = lookup.findStatic(MethodHandleTest.class,"doubleVal", MethodType.methodType(int.class,int.class));
List<Integer> dataList = Arrays.asList(1, 2, 3, 4, 5);
MethodHandleTest.transform(dataList,methodHandle);
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;
}
/**
* 作為引數的方法
* @param val
* @return
*/
public static int doubleVal(int val) {
return val * 2;
}
}
相關文章
- methodHandle* method, JavaCallArguments* args, TRAPSJava
- Java解析Excel例項解析JavaExcel
- java字串解析Java字串
- 【Java】解析xmlJavaXML
- Java解析XMLJavaXML
- Java 解析 ExcelJavaExcel
- Java解析ExcelJavaExcel
- java解析APKJavaAPK
- Java ThreadLocal解析Javathread
- Java JUC CopyOnWriteArrayList 解析Java
- Java面試題解析Java面試題
- 深入解析 Java OutOfMemoryErrorJavaError
- JAVA Method的解析Java
- Java ConcurrentHashmap 解析JavaHashMap
- Java 版抖音解析介面Java
- Java equals 和 == 完全解析Java
- Java 註解完全解析Java
- Java 註解全面解析Java
- Java equals和==完全解析Java
- Java——HashMap原始碼解析JavaHashMap原始碼
- Java——ArrayList原始碼解析Java原始碼
- java解析json listJavaJSON
- Java JUC PriorityBlockingQueue解析JavaBloC
- Java JUC ReentrantLock解析JavaReentrantLock
- Java JUC ThreadPoolExecutor解析Javathread
- java class檔案解析Java
- Java註解全面解析Java
- JAVA進行XML解析JavaXML
- java使用sax解析xmlJavaXML
- Java解析Json字串JavaJSON字串
- Java WeakHashMap 原始碼解析JavaHashMap原始碼
- Java ThreadLocal深度解析Javathread
- Java TreeMap 原始碼解析Java原始碼
- Java集合框架之 Java HashMap 原始碼解析Java框架HashMap原始碼
- Java 基礎:解析 hashCodeJava
- java class 檔案格式解析Java
- Java JUC ConcurrentLinkedQueue解析Java
- Java JUC LinkedBlockingQueue解析JavaBloC