首先,您永远不会将对象设置为 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
有一个引用它的条目。