invoke - JiyangM/spring GitHub Wiki
java7中为间接调用方法引入了新的api,即 方法句柄
方法句柄中包含两个重要的类,MethodHandle和MethodType
- MethodHandle
通过句柄我们可以直接调用该句柄所引用的底层方法。从作用上来看,方法句柄类似于反射中的Method类,是对要执行的方法的一个引用,我们也是通过它来调用底层方法,它调用时有两个方法 invoke和invokeExact,后者要求参数类型与底层方法的参数完全匹配,前者则在有出入时做修改如包装类型。
- MethodType
方法签名不可变对象,是对方法的一个映射,包含返回值和参数类型。在lookup时也是通过它来寻找的。 每个方法句柄都有一个MethodType实例,用来指明方法的返回类型和参数类型。
demo:
public class MethodHandleDemo {
public static void main(String[] args) throws Throwable{
//参数为返回值类型、参数类型 单个参数
MethodType methodType = MethodType.methodType(void.class, String.class);
//声明定义方法句柄,通过lookup对象得到方法句柄,参数为方法所在的类、方法的名称、所匹配的方法签名
MethodHandle methodHandle = MethodHandles.lookup().findVirtual(Test.class, "testMethod", methodType);
//调用底层方法
methodHandle.invoke(Test.class.newInstance(), "hello, world");
//多个参数
MethodHandle testMethod = MethodHandles.lookup().findVirtual(Test.class, "testMethod", MethodType.methodType(Object.class, String.class, int.class));
testMethod.invoke(Test.class.newInstance(), "aa", 1);
MethodType f3 = MethodType.methodType(Object.class, int.class, int.class);
//查找静态方法
MethodHandle aStatic = MethodHandles.lookup().findStatic(Test.class, "add", f3);
//使用invokeExact调用时,参数类型和返回值类型必须与方法签名的一致
aStatic.invokeExact(1, 1234);
//调用静态方法 无法调用private的方法
//aStatic.invoke( 1, 3);
}
}
class Test {
public void testMethod(String str) {
System.out.println("testMethod : "+str);
}
public Object testMethod(String str, int x) {
System.out.println("string = " + str+ " , int = " + x);
return x;
}
/*private*/ public static Object add(int a, int b) {
System.out.println("a + b = " + (a + b));
return a + b;
}
}
-
同反射的区别:
- 效率上比反射高
- 轻量级