如何使用反射访问私有方法?
How do I use reflection to access a private method?
我正在尝试访问 Java 中的 reverse() 中的私有方法。
我尽了最大的努力让它成为可能,但最终失败了。谁能帮我解决这个问题?我只需要成功 运行。也许我可以更改代码。也许我做错了?
错误:
Exception in thread "main" java.lang.NoSuchMethodException: Dummy.foo()
at java.lang.Class.getDeclaredMethod(Class.java:2130)
at Test.main(Dummy.java:22)
Process completed.
我的代码:
import java.util.*;
import java.lang.reflect.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Dummy{
private void foo(String name) throws Exception{
BufferedReader n = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Please give name: ");
name = n.readLine();
StringBuffer o = new StringBuffer(name);
o.reverse();
System.out.print("Reversed string: "+o);
}
}
class Test{
public static void main(String[] args) throws Exception {
Dummy d = new Dummy();
Method m = Dummy.class.getDeclaredMethod("foo");
//m.invoke(d);// throws java.lang.IllegalAccessException
m.setAccessible(true);// Abracadabra
m.invoke(d);// now its OK
}
}
getDeclaredMethod
需要您传递参数类型,以便它可以解析重载方法。
由于您的 foo
方法只有一个类型为 String
的参数,因此以下应该有效:
Method m = Dummy.class.getDeclaredMethod("foo", String.class);
当然您还需要更改 invoke
调用以传递字符串。
或者,您可以使用 MethodHandles。您的 Test
class,重写为使用 MethodHandles
。 (Class Dummy
不变。)
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
public class Test {
public static void main(String[] args) {
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType methodType = MethodType.methodType(void.class, String.class);
try {
lookup = MethodHandles.privateLookupIn(Dummy.class, lookup);
MethodHandle handle = lookup.findVirtual(Dummy.class, "foo", methodType);
handle.invoke(new Dummy(), "");
}
catch (Throwable x) {
x.printStackTrace();
}
}
}
我正在尝试访问 Java 中的 reverse() 中的私有方法。
我尽了最大的努力让它成为可能,但最终失败了。谁能帮我解决这个问题?我只需要成功 运行。也许我可以更改代码。也许我做错了?
错误:
Exception in thread "main" java.lang.NoSuchMethodException: Dummy.foo()
at java.lang.Class.getDeclaredMethod(Class.java:2130)
at Test.main(Dummy.java:22)
Process completed.
我的代码:
import java.util.*;
import java.lang.reflect.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Dummy{
private void foo(String name) throws Exception{
BufferedReader n = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Please give name: ");
name = n.readLine();
StringBuffer o = new StringBuffer(name);
o.reverse();
System.out.print("Reversed string: "+o);
}
}
class Test{
public static void main(String[] args) throws Exception {
Dummy d = new Dummy();
Method m = Dummy.class.getDeclaredMethod("foo");
//m.invoke(d);// throws java.lang.IllegalAccessException
m.setAccessible(true);// Abracadabra
m.invoke(d);// now its OK
}
}
getDeclaredMethod
需要您传递参数类型,以便它可以解析重载方法。
由于您的 foo
方法只有一个类型为 String
的参数,因此以下应该有效:
Method m = Dummy.class.getDeclaredMethod("foo", String.class);
当然您还需要更改 invoke
调用以传递字符串。
或者,您可以使用 MethodHandles。您的 Test
class,重写为使用 MethodHandles
。 (Class Dummy
不变。)
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
public class Test {
public static void main(String[] args) {
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType methodType = MethodType.methodType(void.class, String.class);
try {
lookup = MethodHandles.privateLookupIn(Dummy.class, lookup);
MethodHandle handle = lookup.findVirtual(Dummy.class, "foo", methodType);
handle.invoke(new Dummy(), "");
}
catch (Throwable x) {
x.printStackTrace();
}
}
}