Chr*_*nos 5 java jvm invoke java-8 methodhandle
我要打印 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();
}
Run Code Online (Sandbox Code Playgroud)

的最后一个参数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);
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为Son和Father是同一顶级类的内部类,因此允许访问彼此的私有成员。如果它们不是同一顶级类中的类,in(…)将更改上下文类但清除私有访问权限。在这种情况下,只有 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);
Run Code Online (Sandbox Code Playgroud)
当Father和Son在同一个模块中或Father的模块已打开Father的包到Son的模块进行反射时,此方法有效。
| 归档时间: |
|
| 查看次数: |
157 次 |
| 最近记录: |