In J2EE, many components such as EJB and Servlets give us convenient object lifecycle events to handle setup and cleanup of resources, but did you know that J2SE supports similar functionality? Of course you did for setup. Constructors, static initializers, and member variable initialization give you several options for setup. But in the case of objects, sometimes finalize() just doesn’t cut it. In Windows, I ran a java class with a finalizer and used a ctrl-C to exit. The finalizer didn’t run, since finalization on exit is not guaranteed by default, and may be unsafe. finalize() only executes on garbage collection, and is not guaranteed.
So in a J2SE application, how can you ensure that resources are cleaned up due to an abnormal shutdown? Well, there’s a little gem java.lang.Runtime.addShutdownHook() that takes an unstarted thread as an argument and runs that thread when the system shuts down. So if you had something like a connection pool in a J2SE application, and you needed those connections to die gracefully, if possible, you could define a shutdown hook to close those connections as the JVM shuts down. A kill -9 in *nix or “terminate process” in Windows will still bypass this, but a gentler request such as a kill -3, ctrl-c, or End Task will trigger your cleanup code and let your app die gracefully.
This feature has been available since J2SE 1.3, and while it only solves a few specific types of problem, it’s an interesting tool to add to your bag of tricks.