Mam klasę Dummy
, która ma prywatną metodę o nazwie sayHello
. Chcę zadzwonić pod numer sayHello
spoza domeny Dummy
. Myślę, że powinno być możliwe z refleksją, ale dostaję IllegalAccessException
. Jakieś pomysły???Jak wywołać metodę prywatną spoza klasy java
Odpowiedz
użyć setAccessible(true)
na swoim obiekcie Method przed użyciem metody invoke
.
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
}
}
getMethod również rzuca wyjątek !!! –
ponieważ 'getMethod' zwraca tylko publiczną metodę, potrzebujesz' getDeclaredMethod' – Pshemo
masz rację, dziękuję! –
Najpierw musisz dostać się do klasy, która jest całkiem prosto do przodu, a następnie uzyskać stosując metodę według nazwy getDeclaredMethod
wtedy trzeba ustawić metodę jak dojechać setAccessible
metody na obiekcie Method
.
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);
Jeśli chcesz przekazać dowolny parametr do funkcji prywatnej można przekazać go jako drugim, trzecim ..... argumentów funkcji invoke. Poniżej znajduje się przykładowy kod.
Method meth = obj.getClass().getDeclaredMethod("getMyName", String.class);
meth.setAccessible(true);
String name = (String) meth.invoke(obj, "Green Goblin");
Pełny przykład widać Here
Przykład dostępu metodę prywatnej (z parametrem) używając Java odbicie w następujący sposób:
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);
}
}
nie jest idea prywatny, że nie można zadzwonić z zewnątrz? – PriestVallon
Tak, jest to możliwe dzięki refleksji, ale celem prywatnym jest utrudnianie wywoływania metod z zewnątrz. Może to nie powinno być prywatne? –
@robert jest w tym samym programie (module) –