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

时间:2015-06-25 19:10:23

标签: java hashmap

I have this simple program, where I am iterating over the map and setting the object to null instead of updating the value to null inside map. I am wondering why it is not allowing me to nullify the object but if I change any value of the object while iterating, Objects appears as changed, Please help me understand this behaviour. (This question might sound like a newbie) 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}

3 个答案:

答案 0 :(得分:3)

There are two things coming into play here: local scope of variables, and the behavior of reference types compared to primitive types. When you have for (MyObj i : map.values().toArray(ar)), i is local to the scope of the for and merely points to instances of MyObj. It is a copy of the reference. When you set i to null, you've simply changed the local value of i (i.e., the copy); the original reference still points to the original instance. Since i only points to instances of MyObj, you aren't changing instances of MyObj itself. Really, when you set something to null, you're only saying that it doesn't point to something. When it is non-null, it points to an instance of its type. However, if you do something with i, by calling a method perhaps, you are calling it on the instance that i points to. This is because both the original reference and the copy point to the same thing. So you end up modifying the object itself. For example, let's say you do i.setFoo(10), then you will be modifying the instance of MyObj that i points to, and setting the value of foo on that instance to 10. It is important to understand that with reference types, simply reassigning the value of the variable to null (or any other instance) does not modify the object that it points to. All you've done is made the variable point to something else (or nothing at all in the case of null). Now you will also see the same thing if you had an array of primitives (let's say int[]): for(int i : intArr) { i = 10; } This will not set every location in intArr to 10. Why? This is because i is again a local variable in this case. So this i is a copy of a value in intArr. So when you reassign the value to something else, you simply changed the value of the copy and not the original.

答案 1 :(得分:2)

No it won't. It won't change a thing in map, as you are assigning null to local variable. That local variable used to refer to map value earlier, but refer to null now, without changing the map value itself.

答案 2 :(得分:2)

您可以将o视为包含MyObj实例所在的内存地址的变量。当您编写o = null时,您会从o中删除内存地址,但这不会影响MyObj对象。

在实践中,它有点复杂,但实际上,它是如何运作的。