Ho una classe Dummy
che ha un metodo privato chiamato sayHello
. Voglio chiamare sayHello
dall'esterno Dummy
. Penso che dovrebbe essere possibile con il riflesso ma ottengo un IllegalAccessException
. Qualche idea???Come chiamare un metodo privato dall'esterno di una classe java
risposta
utilizzare setAccessible(true)
sull'oggetto Method prima di utilizzare il suo metodo 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 genera anche un'eccezione !!! –
perché 'getMethod' restituisce solo il metodo pubblico, è necessario' getDeclaredMethod' – Pshemo
hai ragione, grazie! –
Prima devi ottenere la classe, che è piuttosto semplice, quindi ottenere il metodo con il nome utilizzando getDeclaredMethod
allora avete bisogno di impostare il metodo di come accessibile in setAccessible
metodo sull'oggetto 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);
Se si desidera passare qualsiasi parametro di funzione privata è possibile passare come secondo, terzo ..... argomenti della funzione invoke. Di seguito è riportato un codice di esempio.
Method meth = obj.getClass().getDeclaredMethod("getMyName", String.class);
meth.setAccessible(true);
String name = (String) meth.invoke(obj, "Green Goblin");
esempio completa si può vedere Here
esempio di accesso metodo privato (con parametri) utilizzando Java riflessione come segue:
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);
}
}
non è l'idea di privato che non è possibile chiamalo da fuori? – PriestVallon
Sì, è possibile con la riflessione, ma il punto di privato è rendere più difficile chiamare metodi dall'esterno. Forse non dovrebbe essere privato? –
@robert è nello stesso programma (modulo) –