簡體   English   中英

可以在Java中更改內部類的外部類實例嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM