gpt4 book ai didi

java - 我想打印 hi GrandFather;但它似乎打印 hi Father

转载 作者:行者123 更新时间:2023-12-01 10:59:13 25 4
gpt4 key购买 nike

我要打印 hi GrandFather
但它似乎印喜父亲。而且我不明白如何区分 findSpecial 之间的使用和 findVirtual
我希望有人可以帮助我。谢谢

class GrandFather{
void thinking(){
System.out.println("hi GrandFather");

}
}
class Father extends GrandFather{
void thinking(){
System.out.println("hi Father");
}
}
class Son extends Father{
void thinking(){
MethodType mt=MethodType.methodType(void.class);

//MethodHandle mh=MethodHandles.lookup().findVirtual(GrandFather.class,"thinking",mt).bindTo(this);
MethodHandle mh;
mh = MethodHandles.lookup().findSpecial(GrandFather.class,"thinking",mt,getClass());
mh.invoke(this);
}
}
public static void main(String[] args){
(new MethodHandleTest().new Son()).thinking();
}

console screenshot showing "hi Father" printed

最佳答案

findSpecial 的最后一个参数指定调用的上下文类。您指定了 getClass() ,这将导致 Son.class .一个 super来自 Son 的调用只能在 Father 结束,就像普通的 super.thinking()调用源代码。

您需要指定 Father.class作为上下文类,如 Father允许执行 super调用 GrandFather .如果您在不做进一步更改的情况下执行此操作,您会得到像 java.lang.IllegalAccessException: no private access for invokespecial… 这样的异常。 .您必须更改 lookup() 的上下文对象,以便能够访问 private Father 的特点:

MethodType mt = MethodType.methodType(void.class);
MethodHandle mh = MethodHandles.lookup().in(Father.class)
.findSpecial(GrandFather.class, "thinking", mt, Father.class);
mh.invoke(this);

这行得通,因为 SonFather是同一顶级类的内部类,因此允许访问彼此的私有(private)成员。如果它们不是同一顶级类中的类, in(…)将更改上下文类但清除私有(private)访问权限。在这种情况下,只有 Java 9 和更新版本有官方解决方案:
MethodType mt = MethodType.methodType(void.class);
MethodHandle mh = MethodHandles.privateLookupIn(Father.class, MethodHandles.lookup())
.findSpecial(GrandFather.class, "thinking", mt, Father.class);
mh.invoke(this);

这适用于 FatherSon在同一个模块或 Father的模块已打开 Father的包裹到 Son的反射模块。

关于java - 我想打印 hi GrandFather;但它似乎打印 hi Father,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60322808/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com