170 votes

Une manière d'invoquer une méthode privée?

J'ai une classe qui utilise le langage XML et de réflexion pour revenir Objects pour une autre classe.

Normalement, ces objets sont sous les champs d'un objet externe, mais de temps en temps c'est quelque chose que je veux générer à la volée. J'ai essayé quelque chose comme ça, mais en vain. Je crois que c'est parce que Java ne vous permettra pas d'accéder private méthodes de réflexion.

Element node = outerNode.item(0);
String methodName = node.getAttribute("method");
String objectName = node.getAttribute("object");

if ("SomeObject".equals(objectName))
    object = someObject;
else
    object = this;

method = object.getClass().getMethod(methodName, (Class[]) null);

Si la méthode est - private, il échoue avec un NoSuchMethodException. J'ai pu le résoudre en faisant la méthode public, ou de faire une autre classe pour le calculer à partir.

Longue histoire courte, je me demandais juste si il y avait un moyen d'accéder à un private méthode par réflexion.

331voto

erickson Points 127945

Vous pouvez invoquer la méthode privée avec la réflexion. Modifier le dernier bit de la posté code:

method = object.getClass().getDeclaredMethod(methodName);
method.setAccessible(true);
Object r = method.invoke(object);

Il ya un couple de mises en garde. Tout d'abord, getDeclaredMethod ne trouverez méthode déclarée dans le courant Class, pas hérité de aux supertypes. Donc, traverse le béton de classe de la hiérarchie si nécessaire. Deuxièmement, une SecurityManager peut empêcher l'utilisation de l' setAccessible méthode. Donc, il peut être nécessaire d'exécuter en tant que PrivilegedAction (à l'aide d' AccessController ou Subject).

35voto

Utilisez getDeclaredMethod() pour obtenir un objet Méthode privé, puis utilisez method.setAccessible() pour permettre de l'appeler.

31voto

gKaur Points 101

Si la méthode accepte un type de données non primitif, vous pouvez utiliser la méthode suivante pour appeler une méthode privée de n'importe quelle classe:

 public static Object genericInvokMethod(Object obj, String methodName,
            int paramCount, Object... params) {
        Method method;
        Object requiredObj = null;
        Object[] parameters = new Object[paramCount];
        Class<?>[] classArray = new Class<?>[paramCount];
        for (int i = 0; i < paramCount; i++) {
            parameters[i] = params[i];
            classArray[i] = params[i].getClass();
        }
        try {
            method = obj.getClass().getDeclaredMethod(methodName, classArray);
            method.setAccessible(true);
            requiredObj = method.invoke(obj, params);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        return requiredObj;
    }
 

Les paramètres acceptés sont obj, methodName, le nombre de paramètres acceptés et les paramètres. Par exemple

 public class Test {
private String concatString(String a, String b) {
    return (a+b);
}
}
 

La méthode concatString peut être appelée en tant que

 Test t = new Test();
    String str = (String) genericInvokMethod(t, "concatString", 2, "Hello", "Mr.x");
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X