如你所见,使用new运算符可以把空闲的内存空间分配给对象.如前所述,内存不是无限的,而空闲内存也是可能耗尽的.因此,new可能会因为没有足够的空闲空间来创建对象而失败.动态分配内存方案的关键就是回收无用对象占用的内存,以使内存用于后面的分配.在许多程序设计语言中,释放已经分配的内存是手动来处理的.例如,C++中,要使用delete运算符来释放分配的内存.Java使用一种不同的,更方便的方法–垃圾回收(garbage collection)
Java的垃圾回收系统会自动回收对象,透明的在后台操作,无需程序员干预.具体工作方式为:当不存在对某对象的任何引用时,该对象就被认定为没有存在的必要了,他说占用的内存就要被释放,被回收的内存可以用于以后的分配.
问:为什么对于基本数据类型(如int或float)的变量,不需要new?
答:Java的基本数据类型不是作为对象来实现的,出于效率的原因.他们是作为”普通”变量来实现的.基本类型的变量包含赋给他的值.如前所述,对象变量应用了对象.这种间接的层次(和其他对象特性)增加了对象的开销,而基本数据类型则没有这种开销.
垃圾回收只在程序执行的过程中偶尔发生.并不是只要有一个或更多个不再使用的对象,就会发生垃圾回收.为了提高效率,垃圾回收器通常只在满足两个条件时才运行:有对象要回收和需要回收这些对象.切记垃圾回收要占用时间,因此Java运行时系统只在需要的时候才使用此机制.因此无法知道垃圾回收发生的准确时间.
finalize()方法
我们可以定义一个方法,在对象最后被垃圾回收器销毁之前调用他.该方法名为finalize().他可以用于确保对象完全终止.例如,可以使用finalize()来确保对象拥有的一个打开的文件关闭.
为了向类添加一个终止器,只需定义finalize()方法即可.Java运行时环境只要在回收该类的一个对象时,就会调用该方法.在finalize()方法中,要指定在对象被销毁前必须执行的动作.
finalize()方法的基本形式如下所示:
protected void finalize() { //finalization code here }
这里,protected关键字是防止类以外的代码访问finalize()的说明符.
调用finalize()是在垃圾回收之前,理解这一点非常重要.当对象不在作用中时,是不会调用他的.这就意味着不知道何时执行finalize(),甚至finalize()是否会执行.例如,如果程序在垃圾回收发生之前结束,就不会执行finalize().因此,这就需要把他做为一个后备过程来确保对某些资源的合理处理,或用于特殊用途的应用程序,而不是程序在普通操作中使用的方法.简言之,finalize()是一个特殊的方法,大多数程序很少用到他.
问:我知道C++定义了一种名为析构函数(destructor)的特殊函数,可以在销毁对象时自动执行,finalize()与析构函数一样吗?
答:Java没有析构函数,尽管finalize()方法与析构函数的功能接近,但两者并不一样.例如,C++析构函数总是在对象不在作用域之前被调用,但是对于任何具体对象,都不知道何时调用finalize().坦率的讲,因为Java使用了垃圾回收,所以没有必要使用析构函数了.