Originally posted by Ernest Friedman-Hill:
If you've written a class with a "close()" or "dispose()" or "cleanup()" method -- something that the user is supposed to call when they are done with an object -- putting a call to that method in a finalize() method is a sensible thing to do just to be safe, but not necessary. Classes like FileWriter, java.awt.Graphics, etc, do what I've described here.
I think that, in these cases, an assertion should be added to finalize(). This means that your developer builds will throw an assertion failure if you have forgotten to close something. But assertions are disabled (if you've built things right) in release builds, so your release builds will have the protection of the finaliser to close anything that you forgot.