簡體   English   中英

在迭代HashMap時將對象設置為null是否對對象的狀態有任何影響

[英]Does setting an object to null while iterating over a HashMap have any effect on the object's state

我有這個簡單的程序,在其中迭代地圖並將對象設置為null,而不是在map內部將值更新為null。 我想知道為什么不允許我無效該對象,但是如果我在迭代時更改了該對象的任何值,則對象顯示為已更改,請幫助我了解此行為。 (這個問題聽起來像是新手)

Map<String, MyObj> map = new HashMap<>();
map.put("a", new MyObj("XYZ"));
map.put("b", new MyObj("FOO"));
map.put("c", new MyObj("BAR"));

System.out.println(map);

// output : {a=sample.MyObj@15db9742, b=sample.MyObj@6d06d69c, c=sample.MyObj@7852e922}
for(Entry<String, MyObj> e : map.entrySet()){
        MyObj o = e.getValue();
        //set the object to null
        o = null;

}
// printing map to see if values are null now.
System.out.println(map);

// output : {a=sample.MyObj@15db9742, b=sample.MyObj@6d06d69c, c=sample.MyObj@7852e922}

這里有兩件事在起作用:變量的局部范圍,以及與原始類型相比引用類型的行為。

當您擁有for (MyObj i : map.values().toArray(ar))ifor范圍內,僅指向MyObj實例。 它是參考的副本 i設置為null時,您只需更改i的本地值(即副本)即可; 原始引用仍指向原始實例。 由於i指向 MyObj實例, MyObj您不會更改MyObj本身的實例。 確實,當您將某物設置為null ,您只是在說它並不指向某物。 當它為非null時,它指向其類型的實例。

但是,如果你做的東西 i ,通過調用一個方法也許,你對實例調用它i 這是因為原始引用和副本都指向同一事物 因此,您最終修改了對象本身 例如,假設您執行i.setFoo(10) ,那么您將修改i指向的MyObj實例, MyObj該實例上foo的值設置為10

重要的是要了解,對於引用類型 ,只需將變量的值重新分配為null (或任何其他實例) 就不會修改其指向的對象 您要做的只是使變量指向其他內容 (如果為null ,則什么都沒有)。

現在,如果您有一個原始數組(例如int[] ),您還將看到相同的東西:

for(int i : intArr) {
    i = 10;
}

這不會將intArr每個位置都設置為10。為什么? 這是因為在這種情況下, i還是一個局部變量 所以這個i是一個值的副本intArr 因此,當您將值重新分配給其他內容時,您只需更改副本的值即可,而不更改原始值。

不,不會。 它不會更改map中的任何內容,因為您正在將null分配給局部變量。 該局部變量以前曾引用過地圖值,但現在引用了null,而沒有更改地圖值本身。

您可以將o視為一個變量,該變量保存MyObj實例所在的內存地址。 當您將o = null寫入時,將從o刪除內存地址,但這不會影響MyObj對象。

在實踐中,它有點復雜,但是本質上就是這樣。

暫無
暫無

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

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