这个问题原贴发表在这儿:
http://topic.csdn.net/u/20090408/13/89c22659-e194-488d-add1-23256b22465e.html?seed=2029607558
虽然是C#技术栏目,但对JAVA完全适用。
但所以答案没有一个是正确且完整的。
下面是我的答案,我有足够的自信说这是真正正确的答案,除非JVM和CLR规范重新修改了。
正常情况下生成一个对象后主动让 obj = null;
没有任何作用,但也没有任何害处(除了说明程序员对编译器的无知和代码看起来比较幼稚)
编译器比你更清楚在什么位置对象已经失去引用。
object o = new object();
stmt1;
o.xxx();
stmt2;
stmt3;
o = null;
其实编译器在为o.xxx()后面就知道它(原来o指向的那个对象)是可回收的,
比你在两个语句后再o=null更准确!
什么时候需要 o = null;?
o = null;有时是必须的,就是在底层容器中保存对象然后外部封装类pop出来的时候。
比如一个Queue,它的实现是用一个成员变量数组来保存对象
class MyQueue{
private object[] arr = new object[100];
private int tail;
private int head;
private int count;
............;
}
当压入元素时:
if(count >= 100) throw 一个没有空间的异常
this.arr[this.tail] = o;
tail = (tail + 1) % this.arr.length; //如果到数组最后则从头开始
count++;
但当弹出时:
if(count <= 0) return null;
object o = this.arr[this.head];
this.arr[this.head] = null;
this.head = (this.head + 1) % this.arr.length;
count--;
this.arr[this.head] = null;这里如何不主动设置null.则这个对象被pop出去后
arr中始终有一个引用指向这个对象而使对象不能回收,如果你只是临时放一个对象到
Queue中马上就POP出来使用,本来你以为使用后可以被回收,却因为arr中同时有一个
引用指向它,如果这个引用不被其它元素替换掉,则原来那个对象一直不能被回收。
凡是类似的有底层容器和外部封装同时对一个对象持有多个引用的,在你用完了这个对象后
你应该把其它指向它的引用手工置为null;其它情况(指正常的只有一个引用时)不应该置为null
(完全是多余)
其实上面的情况相当于: object o = new object();
o1 = o;
o.xxx();//使用完了,使用完了的意思是我知道o1也不需要再操作这个对象
//我本来想在这个位置对象进入可回收的状态,但因为o1还没有超出作用域,
//所以不能被回收,所以要手工设置o1 = null;
//这样这个对象才会被回收。
}
}