[英]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))
, i
在for
范圍內,僅指向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.