Most GUI examples show System.exit(0) as the window closing event
handler. However, System.exit(0) is a bad way to exit applications.
The specification says that the VM will exit when all the non-daemon
threads have finished. How can this be implemented so as to avoid the
hard exit of System.exit(0)?
The reason most GUI examples use System.exit(0) to terminate the
application is twofold. First, they are examples, and it is the most
expedient way to guarantee that the example will exit properly on all
JVMs. The second reason is historical. Simply put, System.exit() was
the only way you could exit a GUI application. Consider the
following. If the JVM must exit when all non-daemon threads have
terminated and the AWT thread is made a daemon thread, then your
application would exit immediately after main() returned. AWT
programs will never exit if you don't use System.exit() because the
AWT thread is not a daemon thread. This has been a bug in JDKs 1.0.x
through 1.3. Sun has considered various solutions for fixing it, but
has never adopted one because it would break too many existing
applications. The latest word is that they will try to remedy the
situation in the JDK after 1.3 (Kestrel), code-named Merlin.
I should add that System.exit() is not an entirely unacceptable means of
terminating a program. In JDK 1.1, you could guarantee finalizers
would run before exiting by using System.runFinalizersOnExit(). This
was deprecated in JDK 1.2 because of race conditions. JDK 1.3 has
added Runtime.addShutdownHook(), which allows you to specify cleanup
code that should be run before exiting. The problem, of course, is
that there is no way to clean up that works in JDKs 1.1 through 1.3.
I believe this is further evidence that Java needs to be specified
through a formal standards body, which might avoid the pitfalls Sun
keeps on creating for developers.