Class Object provides a method:
public void finalize();
which is called when an object is garbage-collected.
A developer can override finalize to do some house-keeping or sanity checking when an object is disposed of. For example, finalize
could be used to ensure that an object has released resources such as file handles before the object is deallocated.
Typically finalize is used for defensive programming: to guard against unintentional errors (e.g., forgetting to close a file)
that may have occurred elsewhere in
the program.
In this question, we will use finalize to observe the behaviour of the garbage collector.
Disclaimer: This exercise is purely educational, to let you see the garbage collector in action,
and to get more experience writing simple Java programs. You should never write a real program that abuses finalize in this way!
Write a class, A, with a private int field called id. A should have a single constructor, which
should take an integer parameter used to initialise id.
In addition, A should have a package-visible static field, numCollected, initialised to zero.
Override finalize in A. Your implementation of finalize should print a message, saying that the instance of A
with id id has been garbage collected. After printing this message, the static field numCollected should be incremented.
Finally, write a main method that creates a million instances of A, with increasing ids, in a loop, but does not assign any of these instances to a reference variable. (To create but not assign a new instance of A, you simply write a statement: new A(...);)
Run your program several times and inspect the output it produces.
What does this tell you about the garbage collector? What guarantees are provided on how finalize will be invoked?