要通过反射实例化成员内部类,必须用“$”获取其Class对象并传入外部类实例;构造器需显式声明外部类类型参数,且调用前须setAccessible(true)并传入外部类对象。

要通过反射获取内部类的私有构造器并完成实例化,关键在于两点:一是正确获取带访问权限的构造器对象,二是传入合法的外部类实例——因为成员内部类天然持有对外部类的隐式引用。
获取内部类的Class对象需用“$”符号连接
Java编译后,成员内部类的字节码文件名格式为 外部类名$内部类名.class。不能直接写 Outer.Inner.class(这在源码中合法,但反射时需走运行时路径)。
- 正确方式:用
Class.forName("com.example.Outer$Inner") - 或从已有外部类实例出发:
outerInstance.getClass().getDeclaredClasses()[0](需确保顺序确定) - 注意:静态内部类不依赖外部类实例,可直接用
Outer.StaticInner.class
构造器获取必须显式声明外部类类型参数
即使内部类定义的是无参构造器,反射调用时仍需在参数列表中加入外部类的 Class 类型——这是JVM层面的强制要求,否则会抛 NoSuchMethodException。
- 错误写法:
innerClass.getDeclaredConstructor()→ 找不到匹配构造器 - 正确写法:
innerClass.getDeclaredConstructor(Outer.class) - 若内部类还有其他参数(如
String name),则完整写为:innerClass.getDeclaredConstructor(Outer.class, String.class)
实例化前必须设为可访问,并传入外部类对象
私有构造器默认不可见,且 newInstance 调用时第一个实参必须是外部类实例。
- 调用
constructor.setAccessible(true)解除访问限制 - 创建实例时:
constructor.newInstance(outerInstance, "hello") - 若漏传
outerInstance,会报IllegalArgumentException: object is not an instance of declaring class
嵌套对象变量的完整实战流程
假设 Order 类含私有内部类 Item,且 Item 构造器为 private Item(Order order, String sku):
- 1. 加载内部类:
Class> itemClass = Class.forName("com.example.Order$Item"); - 2. 获取构造器:
Constructor> ctor = itemClass.getDeclaredConstructor(Order.class, String.class); - 3. 开放权限:
ctor.setAccessible(true); - 4. 实例化:
Object item = ctor.newInstance(orderObj, "SKU-001");

















