THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

}


// ...


public synchronized void close() throws IOException {
if (file != null) {
file.close();
file = null;
}
}


protected void finalize() throws Throwable {
try {
close();
} finally {
super.finalize();
}
}
}


Note that close is carefully written to be correct if it is invoked more than once. Otherwise, if someone
invoked close, finalizing the object would cause another close on the file, which might not be allowed.


Note also that, in this example, finalize invokes super.finalize in a finally clause. Train
yourself so that you always write that invocation in any finalize method you write. If you don't invoke
super.finalize, you may correctly finalize your own part of the object, but the superclass's part will not
get finalized. Invoking super.finalize is one of those good habits you should adopt even when your
class doesn't extend any other class. In addition to being good training, invoking super.finalize in such
a case means that you can always add a superclass to a class like ProcessFile without remembering to
examine its finalize method for correctness. Invoking the superclass's finalize method in a finally
clause ensures that the superclass's cleanup will happen even if your cleanup causes an exception.


The garbage collector may reclaim objects in any order or it may never reclaim them. Memory resources are
reclaimed when the garbage collector thinks the time is appropriate. Not being bound to an ordering
guarantee, the garbage collector can operate in whatever manner is most efficient, and that helps minimize the
overhead of garbage collection. You can, if necessary, invoke the garbage collector to try to force earlier
collection using System.gc or Runtime.gc, as you'll see in the next section, but there is no guarantee
that garbage collection will actually occur.


When an application exits, no further garbage collection is performed, so any objects that have not yet been
collected will not have their finalize methods invoked. In many cases this will not be a problem. For
example, on most systems when the virtual machine exits, the underlying system automatically closes all open
files and sockets. However, for non-system resources you will have to invent other solutions. (Temporary files
can be marked as "delete on exit," which solves one of the more common issuessee "The File Class" on page
543.)


Reference queuesdiscussed on page 459provide a better way of performing clean-up actions when an object is
it about to be, or has been, reclaimed.


17.3.1. Resurrecting Objects during finalize


A finalize method can "resurrect" an object by making it referenced againfor example, by adding it to a
static list of objects. Resurrection is discouraged, but there is nothing the system can do to stop you.

Free download pdf