可以在Java中更改内部类的外部类实例吗?

在Java中,每当创建内部类实例时,它都与外部类的实例相关联。 出于好奇,是否可以将内部类与外部类的另一个实例相关联?

是的,这是可能的,虽然这对我来说听起来真是个糟糕的主意。 我们的想法是使用reflection设置指向外部实例的final指针(不保证成功)。

 import java.lang.reflect.*; public class Me { final String name; Me(String name) { this.name = name; } class InnerMe { String whoAreYou() { return name; } } InnerMe innerSelf() { return new InnerMe(); } public static void main(String args[]) throws Exception { final Me me = new Me("Just the old me!"); final InnerMe innerMe = me.innerSelf(); System.out.println(innerMe.whoAreYou()); // "Just the old me!" Field outerThis = innerMe.getClass().getDeclaredFields()[0]; outerThis.setAccessible(true); outerThis.set(innerMe, new Me("New and improved me!")); System.out.println(innerMe.whoAreYou()); // "New and improved me!" } } 

这里的关键部分是outerThis.setAccessible(true); – SecurityManager可以强制执行禁止成功的策略。

如果您正在谈论实例化时间,可以使用以下语法:

 public class Outer { public class Inner {} } ... Outer o = new Outer(); Outer.Inner i = o.new Inner(); 

但是,不可能(没有setAccessible(true) )将内部类的现有实例与外部类的另一个实例相关联,因为指向封闭实例的字段是final

 javap Outer$Inner Compiled from "Outer.java" public class Outer$Inner extends java.lang.Object{ final Outer this$0; public Outer$Inner(Outer); } 

你应该能够使用reflection。

只需获取内部类的所有字段( getClass().getDeclaredFields() )并查看哪个字段包含父项,然后更改它(使用field.set(innerInstance, newParent) 。在此之前,您应该使该字段可访问 – setAccessible(true) ))

由于该字段似乎是final ,您可以查看本文以了解如何规避它。

也就是说,你根本不应该这样做 – 这将是一个双重丑陋的黑客,没有实际收益。