清除或设置null到java中的对象

anz*_*aan 19 java null memory-management deep-copy shallow-copy

我最近正在考虑释放Java对象占用的内存.在这样做时,我对如何在Java中复制(浅/深)对象以及如何避免在对象仍处于使用状态时意外清除/无效而感到困惑.

考虑以下场景:

  1. 将a ArrayList<Object>作为参数传递给方法.
  2. 将a传递ArrayList<Object>给可由线程处理的runnable类.
  3. 投入ArrayList<Object>一个HashMap.

现在在这种情况下,如果我打电话,list = null;或者list.clear();对象会发生什么?在这种情况下,对象会丢失,在哪种情况下只将引用设置为null?

我想这与浅层和深层复制对象有关,但在哪些情况下会发生浅层复制,在这种情况下,深层复制是否发生在Java中?

Jon*_*eet 43

首先,您永远不会将对象设置为null.这个概念毫无意义.您可以null变量赋值,但需要非常仔细地区分"变量"和"对象"的概念.一旦你这样做,你的问题就会回答:)

现在在"浅拷贝"和"深拷贝"方面 - 这里可能值得避免使用术语"浅拷贝",因为通常浅拷贝涉及创建新对象,而只是直接复制现有对象的字段.深拷贝将获取这些字段引用的对象的副本(对于引用类型字段).这样一个简单的任务:

ArrayList<String> list1 = new ArrayList<String>();
ArrayList<String> list2 = list1;
Run Code Online (Sandbox Code Playgroud)

......没有做任何浅表复制或在这个意义上的深层复制.它只是复制参考.在上面的代码之后,list1并且list2是自变量 - 它们恰好恰好具有相同的值(引用).我们可以改变其中一个的值,它不会影响另一个:

list1 = null;
System.out.println(list2.size()); // Just prints 0
Run Code Online (Sandbox Code Playgroud)

现在,如果不是更改变量,而是对变量值引用的对象进行更改,那么更改也将通过另一个变量可见:

list2.add("Foo");
System.out.println(list1.get(0)); // Prints Foo
Run Code Online (Sandbox Code Playgroud)

回到原来的问题 - 你永远不会在地图,列表,数组等中存储实际的对象.你只存储引用.当没有"实时"代码到达该对象的方式时,对象只能被垃圾收集.所以在这种情况下:

List<String> list = new ArrayList<String>();
Map<String, List<String>> map = new HashMap<String, List<String>>();
map.put("Foo", list);
list = null;
Run Code Online (Sandbox Code Playgroud)

... ArrayList对象仍然不能被垃圾收集,因为它Map有一个引用它的条目.

  • thnks清除它与浅或深复制无关! (2认同)

sof*_*e99 6

清除变量

据我所知,

如果要重用该变量,请使用

               Object.clear();
Run Code Online (Sandbox Code Playgroud)

如果您不打算重用,那么定义

               Object=null;
Run Code Online (Sandbox Code Playgroud)

注意:与removeAll()相比,clear()更快.

请纠正我,如果我错了......