使用java.lang.invoke.MethodHandle调用私有方法 [英] Invoke private method with java.lang.invoke.MethodHandle
问题描述
如何使用方法句柄调用私有方法?
How can I invoke private method using method handles ?
据我所知,只有两种可公开访问的Lookup
实例:
As far as I can see there are only two kinds of publicly accessible Lookup
instances:
-
MethodHandles.lookup()
-
MethodHandles.publicLookup()
MethodHandles.lookup()
MethodHandles.publicLookup()
,并且都不允许无限制的私人访问.
and neither allows unrestricted private access.
有一个非公开的Lookup.IMPL_LOOKUP
可以满足我的需求.是否有一些公开的方式来获取它(假设SecurityManager允许)?
There is the non-public Lookup.IMPL_LOOKUP
that does what I want. Is there some public way to obtain it (assuming that SecurityManager allows it) ?
推荐答案
结果证明可以使用Lookup#unreflect(Method)并暂时使方法可访问(除非在程序初始化期间完成,否则可能会引入小的安全性问题).
Turns out it's possible with Lookup#unreflect(Method) and temporarily making method accessible (potentially introducing small security issue unless done during program initialization).
这是Thorben的答案中修改的主要方法:
Here is modified main method from Thorben's answer:
public static void main(String[] args) {
Lookup lookup = MethodHandles.lookup();
NestedTestClass ntc = new Program().new NestedTestClass();
try {
// Grab method using normal reflection and make it accessible
Method pm = NestedTestClass.class.getDeclaredMethod("gimmeTheAnswer");
pm.setAccessible(true);
// Now convert reflected method into method handle
MethodHandle pmh = lookup.unreflect(pm);
System.out.println("reflection:" + pm.invoke(ntc));
// We can now revoke access to original method
pm.setAccessible(false);
// And yet the method handle still works!
System.out.println("handle:" + pmh.invoke(ntc));
// While reflection is now denied again (throws exception)
System.out.println("reflection:" + pm.invoke(ntc));
} catch (Throwable e) {
e.printStackTrace();
}
}
这篇关于使用java.lang.invoke.MethodHandle调用私有方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!