Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to invoke private method via Reflection when parameter of method is List?

How can I invoke private method via Reflection API?

My code

public class A {
    private String method(List<Integer> params){
        return "abc";
    }
}

And test

public class B {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class<A> clazz = A.class;
        Method met = clazz.getMethod("method", List.class);
        met.setAccessible(true);
        String res = (String) met.invoke("method", new ArrayList<Integer>());
        System.out.println(res);
    }
}
like image 686
Alex Avatar asked Sep 02 '14 14:09

Alex


2 Answers

There are two problems in your code

  • you are using getMethod which can only return public methods, to get private ones use getDeclaredMethod on type which declares it.
  • you are invoking your method on "method" String literal instead of instance of A class (String doesn't have this method, so you can't invoke it on its instance. For now your code is equivalent to something like "method".method(yourList) which is not correct).

Your code should look like

Class<A> clazz = A.class;
Method met = clazz.getDeclaredMethod("method", List.class);
//                    ^^^^^^^^
met.setAccessible(true);
String res = (String) met.invoke(new A(), new ArrayList<Integer>());
//                               ^^^^^^^
System.out.println(res);
like image 139
Pshemo Avatar answered Sep 18 '22 22:09

Pshemo


You can do it in this way if you need to create an Instance of the A by reflection too

 public static void main(String[] args) throws Exception {
    Class<?> aClass = A.class;
    Constructor<?> constructor = aClass.getConstructors()[0];
    Object a = constructor.newInstance(); // create instance of a by reflection
    Method method = a.getClass().getDeclaredMethod("method", List.class); // getDeclaredMethod for private
    method.setAccessible(true); // to enable accessing private method
    String result = (String) method.invoke(a, new ArrayList<Integer>());
    System.out.println(result);
  }
like image 24
Ahmad Al-Kurdi Avatar answered Sep 21 '22 22:09

Ahmad Al-Kurdi