WebReference.com - Part 5 of chapter 5 from Beginning Java 2 SDK 1.4 Edition, Wrox Press Ltd (5/6)
[previous] [next] |
Beginning Java 2 SDK 1.4 Edition
The finalize() Method
You have the option of including a method finalize()
in a class definition. This method
is called automatically by Java before an object is finally destroyed and the space it occupies in
memory is released. Please note that this may be some time after the object is inaccessible in your
program. When an object goes out of scope, it is dead as far as your program is concerned, but the
Java Virtual Machine may not get around to disposing of the remains until later. When it does, it
calls the finalize()
method for the object. The form of the finalize()
method is:
protected void finalize() {
// Your clean-up code...
}
This method is useful if your class objects use resources that require some special action when
they are destroyed. Typically these are resources that are not within the Java environment and not
guaranteed to be released by the object itself. This means such things as graphics resources--fonts or
other drawing related resources that are supplied by the host operating system, or external files on the
hard disk. Leaving these around after an object is destroyed wastes system resources and, in some
circumstances (with graphics resources under Windows 95 for instance) if you waste enough of them,
your program, and possibly other programs the system is supporting, may stop working. For most classes
this is not necessary, but if an object opened a disk file for example, but did not guarantee its
closure, you would want to make sure that the file was closed when the object was destroyed. You can
implement the finalize()
method to take care of this.
Another use for the finalize()
method is to record the fact that the object has been
destroyed. We could implement the finalize()
method for the Sphere
class to
decrement the value of the static member, count
, for instance. This would make count
a measure of how many Sphere
objects were around, rather than how many had been created.
It would, however, not be an accurate measure for reasons that we will come to in a moment.
You cannot rely on an object being destroyed when it is no longer available to your program code.
Unless your program calls the System.gc()
method, the Java Virtual Machine will only get
rid of unwanted objects and free the memory they occupy if it runs out of memory, or if there is no
activity within your program--for example when waiting for input. As a result objects may not get
destroyed until execution of your program ends. You also have no guarantee as to when a
finalize()
method will be called. All you are assured is that it will be called before
the memory that the object occupied is freed. Nothing time-sensitive should be left to the
finalize()
method.
One consequence of this is that there are circumstances where this can cause problems--when you
don't allow for the possibility of your objects hanging around. For example, suppose you create an
object in a method that opens a file, and rely on the finalize()
method to close it. If
you then call this method in a loop, you may end up with a large number of files open at one time,
since the object that is created in each call of the method will not necessarily be destroyed
immediately on return from the method. This introduces the possibility of your program attempting
to have more files open simultaneously than the host operating system allows. In this situation,
you should make sure a file is closed when you have finished with it, by including an object method
to close it explicitly--for example close()
.
The System
class also provides another possible approach. You can suggest to the JVM
that the finalize()
methods for all discarded objects should be run, if they haven't been
already. You just call the runFinalization()
method:
System.runFinalization();
This is another of those 'best efforts' deals on the part of the JVM. It will do its very best to
run finalize()
for any dead objects that are laying around before return from the
runFinalization()
method, but like with a lot of things in this life, there are no
guarantees.
Native Methods
It is possible to include a method in a class that is implemented in some other programming language,
such as C or C++, external to the Java Virtual Machine. To specify such a method within a class
definition you use the keyword native
in the declaration of the method. For example:
public native long getData(); // Declare a method that is not in Java
Of course the method will have no body in Java since it is defined elsewhere, where all the work is done, so the declaration ends with a semi-colon. The implementation of a native method will need to use an interface to the Java environment. The standard API for implementing native methods in C for example, is called JNI--the Java Native Interface.
The major drawback to using native methods in Java is that your program will no longer be portable. Security requirements for applets embedded in Web pages require that the code must all be written in Java--using native methods in an applet is simply not possible. Since the primary reasons for using Java are the portability of the code and the ability to produce applets, the need for you to add native methods to your Java programs will be minimal. We will, therefore, not delve any deeper into this topic.
[previous] [next] |
Created: August 5, 2002
Revised: August 5, 2002
URL: https://webreference.com/programming/java/beginning/chap5/5/5.html