I want to test a private method that existe inside a private inner class
public class MyBigClass {
private class MyInnerClass {
private void wantedMethod() {
}
}
}
I want to call the wantedMethod()
to test it
Here is my code
Class[] classes = MyBigClass.class.getDeclaredClasses();
for (int i = 0; i < classes.length; i++) {
// this code print "MyInnerClass"
System.out.println(">> inner classes >> " + classes[i].getSimpleName());
if (classes[i].getSimpleName().equals("MyInnerClass")) {
Class clazz = classes[i];
// Constructor c=clazz.getConstructor();
Method[] methods = clazz.getDeclaredMethods();
// this code print "wantedMethod"
for (int j = 0; j < methods.length; j++) {
System.out.println("inner class methods >> " + methods[i].getName());
}
}
}
Problem : I cannot call wantedMethod()
If you want to invoke a non-static method you need to tell on which object you want to invoke it. In your case you want inner class object, but since you don't have one yet you need to create it. Since Java can't let inner class object be created without outer class object you will need to create that outer object too.
So these are steps you need to take:
You can do it like this:
(you just need to remember that default constructors have same visibility as visibility of its class, so private class will have private constructor which we will need to make accessible before we will be able to use it)
try {
//creating parent object
Object outer = new MyBigClass();
//creating inner class object
Class<?> innerClass = Class.forName("MyBigClass$MyInnerClass");
Constructor<?> constructor = innerClass.getDeclaredConstructor(MyBigClass.class);//inner object must know type of outer class
constructor.setAccessible(true);//private inner class has private default constructor
Object child = constructor.newInstance(outer);//inner object must know about its outer object
//invoking method on inner class object
Method method = innerClass.getDeclaredMethod("wantedMethod",new Class<?>[]{});
method.setAccessible(true);//in case of unaccessible method
method.invoke(child,new Object[]{});
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
You can find more info about creating inner class object via reflection in this question