以下代码书上说是输出“i am grandfather”,但远行实际输出为“i am father”
class Test {
class GrandFather {
void thinking() {
System.out.println("i am grandfather");
}
}
class Father extends GrandFather {
void thinking() {
System.out.println("i am father");
}
}
class Son extends Father {
void thinking() {
try {
MethodType mt = MethodType.methodType(void.class);
MethodHandle mh = lookup().findSpecial(GrandFather.class,
"thinking", mt, getClass());
mh.invoke(this);
} catch (Throwable e) {
}
}
}
public static void main(String[] args) {
(new Test().new Son()).thinking();
}
}
求解!
个人理解是这样的:invokespecial
指令用于调用一些需要特殊处理的实例方法,包括实例初始化方法、私有方法和父类方法,对应findSpecial方法返回。此处,MethodHandles.lookup().findSpecial(GrandFather.class, "thinking", mt, getClass())
;你需要查找的是GrandFather
类型,由当前Son
类型作为调用者,调用父类的thinking
方法。由于Son
继承自Father
,而Father
又继承GrandFather
,所以Son
本质也是一个GrandFather
类型。
那么查找GrandFather
类型的thinking
方法,并且是由Son
作为子类调用,最终得到的方法就是Father
类的thinking()
。
这个方法的api是这样描述的:Produces an early-bound method handle for a virtual method.
所以此方法返回的绑定GrandFather
类型的thinking
方法,最终是Father类的thinking()
。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。