Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何调用存在于私有内部类中的私有方法_Java_Reflection_Private Methods - Fatal编程技术网

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

Java 如何调用存在于私有内部类中的私有方法,java,reflection,private-methods,Java,Reflection,Private Methods,我想测试存在于私有内部类中的私有方法 public class MyBigClass { private class MyInnerClass { private void wantedMethod() { } } } 我想调用wantedMethod()来测试它 这是我的密码 Class[] classes = MyBigClass.class.getDeclaredClasses(); for (int i = 0; i < c

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

 public class MyBigClass {
    private class MyInnerClass {
       private void wantedMethod() {
       }
    }
 }
我想调用
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());
            }

        }

    }    
Class[]classes=MyBigClass.Class.getDeclaredClasses();
for(int i=0;i>内部类>>”+类[i].getSimpleName());
if(类[i].getSimpleName().equals(“MyInnerClass”)){
类别clazz=类别[i];
//构造函数c=clazz.getConstructor();
方法[]methods=clazz.getDeclaredMethods();
//此代码打印“wantedMethod”
对于(int j=0;j>”+方法[i].getName());
}
}
}    

问题:我无法调用
wantedMethod()

这是因为您的类没有命名为
codecuit
。如果出现这种情况,请删除该
,它将正常工作

同时删除行
Constructor c=clazz.getConstructor(),因为它会引发异常

进行这些更改后,将打印您自己的代码

>> inner classes >> MyInnerClass
inner class methods >>  wantedMethod
编辑 使用此代码执行该方法

    Class<?>[] classes = MyBigClass.class.getDeclaredClasses();

    for (Class<?> clazz : classes) {
        if(clazz.getSimpleName().equals("MyInnerClass")) {
            Method method = clazz.getDeclaredMethod("wantedMethod", new Class[] {});
            method.setAccessible(true);
            method.invoke(clazz.getDeclaredConstructor(MyBigClass.class).newInstance(new MyBigClass()), new Object[] {});
        }
    }
但是,我假设这就是Java使用反射处理内部(嵌套)类的方式

注意,您必须为内部类提供一个
public
构造函数

public class MyBigClass {
    private class MyInnerClass {
        public MyInnerClass() {
            System.out.println("hello");
        }
        private void wantedMethod() {
            System.out.println("world");
        }
    }
}
您还必须在私有方法上
setAccessible(true)
,才能调用它

编辑2 经过进一步调查,当我反编译生成的
MyBigClass$MyInnerClass.class
类时,我发现我的直觉是正确的:

public class MyBigClass$MyInnerClass {
    public MyBigClass$MyInnerClass(MyBigClass paramMyBigClass) {
        System.out.println("hello");
    }
    private void wantedMethod() {
        System.out.println("world");
    }
}

如果有人能对这种行为有所了解,我会非常高兴。

如果你想调用一个非静态方法,你需要告诉你要在哪个对象上调用它。在您的例子中,您需要内部类对象,但由于您还没有内部类对象,所以需要创建它。因为Java不能在没有外部类对象的情况下创建内部类对象,所以您也需要创建外部对象

因此,您需要采取以下步骤:

  • 创建外部类对象(如果没有)
  • 使用外部类对象创建内部类对象
  • 对内部类对象调用方法
您可以这样做:
(您只需要记住,默认构造函数的可见性与其类的可见性相同,所以私有类将具有私有构造函数,我们需要在能够使用它之前使其可访问)

试试看{
//创建父对象
对象外部=新的MyBigClass();
//创建内部类对象
Class innerClass=Class.forName(“MyBigClass$MyInnerClass”);
构造函数构造函数=innerClass.getDeclaredConstructor(MyBigClass.class);//内部对象必须知道外部类的类型
setAccessible(true);//私有内部类具有私有默认构造函数
Object child=constructor.newInstance(外部);//内部对象必须知道其外部对象
//在内部类对象上调用方法
方法Method=innerClass.getDeclaredMethod(“wantedMethod”,新类[]{});
method.setAccessible(true);//如果是不可访问的方法
调用(子对象,新对象[]{});
}catch(ClassNotFoundException | NoSuchMethodException | SecurityException |实例化Exception | IllegalAccessException | IllegalArgumentException | InvocationTargetException e1){
//TODO自动生成的捕捉块
e1.printStackTrace();
}

您可以在

中找到有关通过反射创建内部类对象的更多信息,最后一个循环不打印任何内容,当我尝试使用method=clazz.getDeclaredMethod(“wantedMethod”,null)调用它时;它抛出了一个NoSuchMethodException:(你能发布你正在运行的确切代码吗?因为你问题中的代码非常适合我。Method Method=clazz.getDeclaredMethod(“wantedMethod”,null);Method.invoke(clazz.getConstructor().newInstance(),null);添加这两行并重试您的代码出现此异常:类testClass无法使用修饰符“private”访问类MyBigClass$MyInnerClass的成员您没有复制行
方法。setAccessible(true);
我猜是这样。复制该行并重试。此外,您应该声明一个
public
构造函数。
public class MyBigClass$MyInnerClass {
    public MyBigClass$MyInnerClass(MyBigClass paramMyBigClass) {
        System.out.println("hello");
    }
    private void wantedMethod() {
        System.out.println("world");
    }
}
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();
}