要想清理对象,用户必须在清理的时候调用一个清理方法。这听上去很简单,但却和C++的拆构函数在概念上有一些冲突。C++的对象都会被清除。或者说,对象都必须被清除。如果C++的对象是以本地的形式创建的(也就是说创建在栈里——Java是不可能做到的),那么用花括号关闭这个作用域的时候,对象就被清除了。如果对象是用new创建的,那么当程序员调用C++的delete运算符的时候(Java里面没有),就会调用对象的拆构函数了。如果C++的程序员忘了调用delete,那么拆构函数就永远也不会被调用,这样就留下了一个内存的漏洞,此外对象的其余部分也不会得到清理了。这种bug是很难察觉的,同时它也是让C++的程序员转向Java的一个重要原因。
Java不允许你创建本地对象——你必须用new。但是Java里面没有释放对象的delete可供调用,因为垃圾回收器会替你释放内存。所以从简化问题的角度来讲,你可以认为有了拦击回收器之后,Java已经不再需要拆构函数了。然而,你会发现垃圾回收器并没有完全取代拆构函数。如果你要进行一些释放内存以外的清理活动,那只能调用Java方法了,这就和C++的拆构函数一样了,一点便宜都占不到。记住,垃圾回收和finalize()都是靠不住的。只要JVM还没到快要耗尽内存的地步,它是不会浪费事件来回收垃圾以恢复内存的。