java.lang.invoke
包主要用于动态确定目标方法
在java语言中无法把函数作为一种参数进行传递,C++
里有函数指针,C#
里有相似的delegate、event类型。在java
里普遍的做法是传递1个实现了某个接口实例作为参数。
MethodHandle
可以让java语言拥有跟函数指针类似的工具
public class AncestorsRelation {
class Grandfather{
public void say(){
System.out.println("It's grandfather said!");
}
}
class Father extends Grandfather{
public void say(){
System.out.println("It's father said!");
}
}
class Son extends Father{
public void say(){
//如何在此处调用Grandfather的say方法
//方法1:
//new Grandfather().say();
//方法2:
//使用MethodHandle调用Grandfather的构造函数后再调用say方法
}
}
}
第二种方法实现如下
public void say(){
System.out.println("It's son said!");
//使用MethodType构造出要调用方法的返回类型
MethodType methodType = MethodType.methodType(void.class);
try {
//找到祖父类的构造函数
MethodHandle inithandle = MethodHandles.lookup().findConstructor(Grandfather.class, methodType);
//获取祖父类实例对象
Object o = inithandle.invoke();
//找到祖父类里被覆写的方法并把该方法绑定到祖父类实例上
MethodHandle handle = MethodHandles.lookup()
.findVirtual(Grandfather.class, "say", methodType).bindTo(o);
//调用祖父类里被父类覆写的方法
handle.invoke();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}