[英]Possible to change the outer class instance of an inner class in Java?
在Java中,每當創建內部類實例時,它都與外部類的實例相關聯。 出於好奇,是否可以將內部類與外部類的另一個實例相關聯?
是的,這是可能的,雖然這對我來說聽起來真是個糟糕的主意。 我們的想法是使用反射設置指向外部實例的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);
}
你應該能夠使用反射。
只需獲取內部類的所有字段( getClass().getDeclaredFields()
)並查看哪個字段包含父項,然后更改它(使用field.set(innerInstance, newParent)
。在此之前,您應該使該字段可訪問 - setAccessible(true)
))
由於該字段似乎是final
,您可以查看本文以了解如何規避這一點。
也就是說,你根本不應該這樣做 - 這將是一個雙重丑陋的黑客,沒有實際收益。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.