Java反射访问内部类实例数据报错:object is not an instance of declaring class
问题分析与解决
兄弟,你遇到的IllegalArgumentException核心原因是反射调用方法时传错了对象,咱们一步步拆解问题:
错误根源
你的循环里,fields是OuterClass的私有成员字段(也就是innerClass1和innerClass2对应的Field实例),但你直接把Field对象本身传给了method.invoke(f, null)。而getId方法是属于InnerClass实例的,Field对象根本不是InnerClass的实例,JVM自然会报错说“对象不是声明类的实例”。
修正步骤
要解决这个问题,你需要:
- 开启私有字段的访问权限(因为
innerClass1和innerClass2是private修饰的,反射默认无法访问) - 从
outerClass实例中获取字段对应的实际InnerClass对象 - 用这个真实的
InnerClass实例去调用getId方法
修正后的代码
import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Reflection { public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { OuterClass outerClass = new OuterClass(); OuterClass.InnerClass innerClass1 = outerClass.new InnerClass(1, "Iftekhar", "1234"); OuterClass.InnerClass innerClass2 = outerClass.new InnerClass(2, "Ahmed", "123"); outerClass.setInnerClass1(innerClass1); outerClass.setInnerClass2(innerClass2); Field[] fields = outerClass.getClass().getDeclaredFields(); // 提前获取InnerClass的getId方法,避免循环内重复反射提升效率 Method getIdMethod = OuterClass.InnerClass.class.getMethod("getId"); for (Field f : fields) { // 跳过非InnerClass类型的字段,避免后续OuterClass新增字段时出错 if (!OuterClass.InnerClass.class.isAssignableFrom(f.getType())) { continue; } // 开启私有字段的访问权限 f.setAccessible(true); // 从outerClass实例中拿到对应的InnerClass对象 OuterClass.InnerClass innerInstance = (OuterClass.InnerClass) f.get(outerClass); // 用真实的InnerClass实例调用getId方法 int id = (int) getIdMethod.invoke(innerInstance); System.out.println(id); } } }
额外优化说明
- 把
getId方法的获取逻辑移到循环外,避免重复执行反射操作,提升代码效率 - 增加字段类型判断,让代码更健壮,后续如果
OuterClass新增其他类型字段,也不会影响现有逻辑
现在运行代码,就能得到你预期的输出:1和2啦。
内容的提问来源于stack exchange,提问作者Sunny
相关产品推荐
相关产品推荐

