簡體   English   中英

在調試Java時,如果變量在IntelliJ IDEA中名稱為“ this $ 0”,那意味着什么?

[英]What does it mean if a variable has the name “this$0” in IntelliJ IDEA while debugging Java?

在此處輸入圖片說明

我試圖通過在調試模式下運行一個稱為testSendStream測試並逐步執行該測試的代碼來理解功能性Java testSendStream庫。

上面的快照顯示了一個名為this$0的奇怪變量。

這個名字從哪里來?

這個名字是什么意思?

為什么這個變量有這個名字?

給它起這個名字的原因是什么?

當然,該名稱並非來自代碼本身,它是由IntelliJ或javac / java生成的。 但為什么 ?

看看如果我用標簽Mystery Object標記該對象會發生什么,也很有趣。

在此處輸入圖片說明

this$0Inner類( 非靜態嵌套類)中的“隱藏字段”,用於保存對Outer類實例的引用,該實例用於創建Inner類的當前實例。

簡而言之,當你有

Outer outer = new Outer();
Outer.Inner inner = oc.new Outer.Inner(); 

Inner所保持的實例inner其將存儲this$0字段參照Outer使用(由為持有相同的附圖來創建它實例outer變量)。

這是必需的,因為嵌套類必須有權訪問外部類的所有成員(包括私有成員)。 如果我們想寫類似methodFromOuterClass();東西methodFromOuterClass(); 在內部類中,JVM需要知道應該在哪個Outer實例上調用此方法。 為了使編譯器有可能將這樣的代碼“更改”為this$0.methodFromOuterClass()


更多細節和示例:

public class Outer {
    private int id;
    public Outer(int id) { this.id = id;}

    public class Inner{
        void printOuterID(){
            System.out.println(id); 
        }
    }
}

現在將在這里打印什么,為什么?

Outer o1 = new Outer(1);
Outer o2 = new Outer(2);
Outer.Inner in1 = o1.new Inner();
Outer.Inner in2 = o2.new Inner();

in1.printOuterID();
in2.printOuterID();

我們會看到

1
2

但是in1如何知道應該從o1而不是從o2打印id值?
這是因為內部類的每個實例都知道它是在外部類的哪個實例上創建的。 這是因為this$0引用存儲了用於創建內部實例的外部實例的引用。
編譯器將此變量添加到所有非靜態內部類中,並在調用時設置其值

Outer.Inner in1 = o1.new Inner(); //`this$0` will be set to hold `o1` instance.

所以像

void printOuterID(){
    System.out.println(id); 
}

基本上等於

void printOuterID(){
    System.out.println(this$0.id); //although we can't access this$0 explicitly
}

是與非靜態內部類有關的約定。 內部類的字節碼將包含對名為this$0的包作用域的引用,該字段使您可以引用封閉類的this對象。 注意,在您的示例中, this$0Mystery Object this變量在其上Mystery Object this的相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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