import com.gd67.javalib.util.reflect.ReflectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
public class TestCallParentParentFunction {
Logger logger = LoggerFactory.getLogger(MainTest.class);
abstract class GParent{
protected void pfun(){
logger.info("gp.pfun");
}
}
class Parent extends GParent{
protected void pfun(){
logger.info("p.pfun");
}
}
class Child extends Parent{
public void pfun(){
// 创建方法类型:无参数,返回值为 void
MethodType methodType = MethodType.methodType(void.class);
// 获取查找器
MethodHandles.Lookup lookup = MethodHandles.lookup();
try {
//否则没权限
//no private access for invokespecial: class TestCallParentParentFunction$GParent, from TestCallParentParentFunction$Child
if(true)
lookup= ReflectHelper.getFied(MethodHandles.Lookup.class,"IMPL_LOOKUP");
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
// 查找爷爷类的 method() 方法句柄,第四个参数改为当前类
MethodHandle grandparentMethod = null;
try {
grandparentMethod = lookup.findSpecial(
GParent.class,
"pfun",
methodType,
GParent.class
);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
// 调用爷爷类的方法
try {
grandparentMethod.invokeExact((GParent)this); // 输出:爷爷类的 method() 被调用?
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
}
public static void main(String[] args) {
Child c= new TestCallParentParentFunction().new Child();
c.pfun();
}
}