Вопрос по call, private, reflection, java – Как вызвать закрытый метод извне класса Java

27

у меня естьDummy класс с закрытым методомsayHello, Я хочу позвонитьsayHello снаружиDummy, Я думаю, что это должно быть возможно с отражением, но я получаюIllegalAccessException, Есть идеи???

@ Роберт в той же программе (модуле) Hamed Rajabi
@PriestVallon Да, я знаю, я не должен делать это в реальной программе, мне просто интересно !!! Hamed Rajabi
Разве не идея частного, что вы не можете назвать это извне? PriestVallon
@HamedRajabi: вы имеете в виду класс, который вызывает приватный метод, и вашDummy класс находится в одной упаковке? Если это так, вы можете использоватьpackage-private (опуская модификатор). Genzer
Да, это возможно с помощью рефлексии, но суть приватности состоит в том, чтобы усложнить вызов методов извне. Может быть этоshouldn't be private? Louis Wasserman

Ваш Ответ

5   ответов
56

использованиеsetAccessible(true) на вашем объекте Method перед использованием его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 также создает исключение !!! Hamed Rajabi
так какgetMethod возвращает только публичный метод, вам нужноgetDeclaredMethod
8
method = object.getClass().getDeclaredMethod(methodName);
method.setAccessible(true);
method.invoke(object);
9

Сначала вы должны получить класс, который довольно прост, а затем получить метод по имени, используяgetDeclaredMethod тогда вам нужно установить метод как доступныйsetAccessible метод наMethod объект.

    Class<?> clazz = Class.forName("test.Dummy");

    Method m = clazz.getDeclaredMethod("sayHello");

    m.setAccessible(true);

    m.invoke(new Dummy());
5

Пример доступа к приватному методу (с параметром) с использованием java отражения:

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);
    }
}
5

Если вы хотите передать какой-либо параметр частной функции, вы можете передать его в качестве второго, третьего ..... аргумента функции invoke. Ниже приведен пример кода.

Method meth = obj.getClass().getDeclaredMethod("getMyName", String.class);
meth.setAccessible(true);
String name = (String) meth.invoke(obj, "Green Goblin");

Полный пример вы можете увидетьВот

Похожие вопросы