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