首先,您永远不会将对象设置为 null。这个概念没有任何意义。您可以为变量赋值,但需要非常仔细地区分“变量”和“对象”的概念。一旦你这样做了,你的问题就会:)null
现在,就“浅复制”与“深度复制”而言 - 这里可能值得避免使用术语“浅复制”,因为通常浅副本涉及创建新对象,但只是直接复制现有对象的字段。深层副本也将获取这些字段所引用对象的副本(对于引用类型字段)。像这样的简单任务:
ArrayList<String> list1 = new ArrayList<String>();
ArrayList<String> list2 = list1;
...从这个意义上说,既不做浅层复制,也不做深度复制。它只是复制引用。在上面的代码之后,并且是自变量 - 它们目前恰好具有相同的值(引用)。我们可以更改其中一个的值,而不会影响另一个:list1
list2
list1 = null;
System.out.println(list2.size()); // Just prints 0
现在,如果我们不是更改变量,而是对变量值引用的对象进行更改,则该更改也将通过另一个变量可见:
list2.add("Foo");
System.out.println(list1.get(0)); // Prints Foo
所以回到你最初的问题 - 你永远不会将实际对象存储在地图,列表,数组等中。您只存储引用。只有当“实时”代码无法再到达该对象时,才能对对象进行垃圾回收。所以在这种情况下:
List<String> list = new ArrayList<String>();
Map<String, List<String>> map = new HashMap<String, List<String>>();
map.put("Foo", list);
list = null;
...该对象仍然无法被垃圾回收,因为 有一个引用它的条目。ArrayList
Map