我有一个名为Dummy的类,其中有一个私有方法叫做sayHello。我想从Dummy外部调用sayHello。我认为可以使用反射来实现,但是我遇到了IllegalAccessException异常。有什么想法吗?
import java.lang.reflect.*;
class Dummy{
private void foo(){
System.out.println("hello foo()");
}
}
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
}
}
setAccessible(true)
。getMethod
仅返回公共方法,所以您需要使用getDeclaredMethod
。 - PshemoIllegalAccessException
,这意味着提问者和读者很可能已经了解使用反射调用方法的通用方式,但是他们在特别处理private
方法时遇到了问题。我们已经有了很多关于通过反射调用带参数方法的问题和答案,例如https://dev59.com/mnVC5IYBdhLWcg3w21Iq#30671481,所以我不需要在这里重复,特别是因为该主题很宽泛,可能需要关于处理原始类型参数、getDeclaredMethod与getMethod之间的区别等问题的信息。 - Pshemo首先,你需要获取类,这很简单明了。然后使用getDeclaredMethod
按名称获取方法,接下来需要在Method
对象上使用setAccessible
方法将该方法设置为可访问状态。
Class<?> clazz = Class.forName("test.Dummy");
Method m = clazz.getDeclaredMethod("sayHello");
m.setAccessible(true);
m.invoke(new Dummy());
method = object.getClass().getDeclaredMethod(methodName);
method.setAccessible(true);
method.invoke(object);
Method meth = obj.getClass().getDeclaredMethod("getMyName", String.class);
meth.setAccessible(true);
String name = (String) meth.invoke(obj, "Green Goblin");
你可以在这里看到完整的示例。
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
class Test
{
private void call(int n) //private method
{
System.out.println("in call() n: "+ n);
}
}
public class Sample
{
public static void main(String args[]) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException
{
Class c=Class.forName("Test"); //specify class name in quotes
Object obj=c.newInstance();
//----Accessing private Method
Method m=c.getDeclaredMethod("call",new Class[]{int.class}); //getting method with parameters
m.setAccessible(true);
m.invoke(obj,7);
}
}
Dummy
类在同一个包中吗?如果是这种情况,你可能想使用package-private
(省略修饰符)。 - Genzer