Java 使用findVirtual调用的Methodhandle私有方法
MethodHandle的Java文档说私有方法应该通过findSpecial调用 有人能解释一下我遗漏了什么吗Java 使用findVirtual调用的Methodhandle私有方法,java,private-methods,methodhandle,Java,Private Methods,Methodhandle,MethodHandle的Java文档说私有方法应该通过findSpecial调用 有人能解释一下我遗漏了什么吗 import java.lang.invoke.MethodHandles; import java.lang.invoke.*; import java.lang.invoke.MethodType; public class PrivateClassMethodLookupTest{ public static void main(String[] args) th
import java.lang.invoke.MethodHandles;
import java.lang.invoke.*;
import java.lang.invoke.MethodType;
public class PrivateClassMethodLookupTest{
public static void main(String[] args) throws Throwable{
new PrivateClassMethodLookupTest().m();
MethodHandle mh = MethodHandles.lookup()
.findVirtual(PrivateClassMethodLookupTest.class, "m", MethodType.methodType(void.class));
mh.invoke(new PrivateClassMethodLookupTest());
}
private void m() { System.out.println("in m");}
}
您之所以能够调用它,是因为您可以从运行
main
的同一类访问私有方法
请尝试运行以下代码:
package com.company;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
public class PrivateClassMethodLookupTest {
public static void main(String[] args) throws Throwable {
new PrivateClassMethodLookupTest.Inner().m();
MethodHandle mh = MethodHandles.lookup()
.findVirtual(PrivateClassMethodLookupTest.Inner.class, "m", MethodType.methodType(void.class));
mh.invoke(new PrivateClassMethodLookupTest.Inner());
}
static class Inner {
private void m() {
System.out.println("in m");
}
}
}
要调用私有方法,应使用反射API并更改方法访问类型:
package com.company;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
public class PrivateClassMethodLookupTest {
public static void main(String[] args) throws Throwable {
new PrivateClassMethodLookupTest.Inner().m();
Method declaredMethod = PrivateClassMethodLookupTest.Inner.class.getDeclaredMethod("m");
declaredMethod.setAccessible(true);
MethodHandle mh = MethodHandles.lookup().unreflect(declaredMethod);
mh.invoke(new PrivateClassMethodLookupTest.Inner());
}
static class Inner {
private void m() {
System.out.println("in m");
}
}
}
有没有一种方法可以从PrivateClassMethodLookupTest调用Inner.m?MethodHandles.lookup().findSpecial(..)不起作用它可以使用反射API方法declaredMethod=PrivateClassMethodLookupTest.Inner.class.getDeclaredMethod(“m”);declaredMethod.setAccessible(true);MethodHandle mh=MethodHandles.lookup().unreflect(declaredMethod);invoke(新的PrivateClassMethodLookupTest.Inner());你知道为什么findSpecial不可能吗?从
中,如果显式指定的调用方类与查找类不相同,或者如果此查找对象没有私有访问权限,则访问失败
@nantitv:如果内部
通过MethodHandles.lookup()创建查找
对象,则有可能
拥有适当的访问权限并将其交给外部类。lookup对象封装了访问,任何获得它的人都可以使用它来查找(并最终调用)关联类的private
方法。