This example illustrates the use of PhantomReference objects to schedule clean-up operations associated with an object. The main method is in the "JarJarToy" class and simply loops creating instances of that class. Each instance creates an associated instance of "JarJarCleanupInfo" which holds all of the state necessary for performing the clean-up of the object. In this case it's simply a number which is printed out in the 'doCleanup' method. Note that "JarJarCleanupInfo" extends "PhantomReference" and that the references are registered with a queue managed by the "JarJarToyCleanupManager" class. When the garbage collector detects that the JarJarToy object referred to from a particular phantom reference has become unreachable it enqueues the phantom reference object on the reference queue of the cleanup manager. The cleanup manager loops taking items from the reference queue and invoking 'doCleanup' on them. This scheme is much more convoluted than simply adding a 'finalize' method to the "JarJarToy" class. However, it has several benefits: - it allows the programmer to decide exactly when the clean-up operations are performed, for example as here they could instantiate a separate thread for this purpose, - it avoids the problem of finalizers that 'resurrect' the object that they are invoked on by writing 'this' into a shared field -- with PhantomReferences it is the reference object rather than the JarJarToy object itself that is available whne running the clean-up code.