如何调用私有内部类中存在的私有方法

jos*_*ino 5 java reflection private-methods

我想测试一个私有内部类中存在的私有方法

 public class MyBigClass {
    private class MyInnerClass {
       private void wantedMethod() {
       }
    }
 }
Run Code Online (Sandbox Code Playgroud)

我想打电话wantedMethod() 来测试它

这是我的代码

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

        }

    }    
Run Code Online (Sandbox Code Playgroud)

问题:我不能打电话wantedMethod()

Psh*_*emo 6

如果要调用非静态方法,则需要告知要调用它的对象.在您的情况下,您需要内部类对象,但由于您还没有内部类对象,因此您需要创建它.由于Java不能在没有外部类对象的情况下创建内部类对象,因此您还需要创建该外部对象.

所以这些是您需要采取的步骤:

  • 创建外部类对象(如果没有),
  • 使用外部类对象创建内部类对象,
  • 调用内部类对象的方法.

你可以这样做:(
你只需要记住默认构造函数与其类的可见性具有相同的可见性,因此私有类将具有私有构造函数,在我们能够使用它之前我们需要使用它们)

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();
}
Run Code Online (Sandbox Code Playgroud)

您可以在此问题中找到有关通过反射创建内部类对象的更多信息