我想测试私有内部类中存在的私有方法
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());
}
}
}
问题:我无法致电wantedMethod()
答案 0 :(得分: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();
}
您可以在this question
中找到有关通过反射创建内部类对象的更多信息答案 1 :(得分:2)
这是因为您的班级未命名为CodeCircuit
。删除if
条件,它将起作用。
同时删除行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[] {});
}
}
语法有点奇怪,使您可以使用外部类来获取内部类构造函数。它的行为就好像你有一个构造函数,在你的内部类中定义了以下签名:
public MyInnerClass(MyBigClass bigClass) {
}
但是,我认为这是Java如何使用反射来处理内部(嵌套)类。
请注意,您必须为内部类提供public
构造函数。
public class MyBigClass {
private class MyInnerClass {
public MyInnerClass() {
System.out.println("hello");
}
private void wantedMethod() {
System.out.println("world");
}
}
}
您还必须对私有方法setAccessible(true)
进行调用才能调用它。
经过进一步调查,当我反编译生成的MyBigClass$MyInnerClass.class
课程时,我发现我的预感是正确的:
public class MyBigClass$MyInnerClass {
public MyBigClass$MyInnerClass(MyBigClass paramMyBigClass) {
System.out.println("hello");
}
private void wantedMethod() {
System.out.println("world");
}
}
如果有人能对这种行为有所启发,那真的很高兴