The answer for most developers is "almost never". Finalize is (in theory) called before an object is garbage collected, or if you make a call to System.runFinalization() (it should be noted however that neither method guarentees all finailers will be run). However since there is no guarentee when (or even if) an object is garbage collected finalize is not a good candidate for the same sort of clean up operations you might perform in a finally block. I can't think of a good reason to use finalize, other than perhaps to observe how the GC is disposing of objects.
And remember the classic case where the finalisation prevents the object from being destructed (by creating new references to it). In that case the finaliser will NOT be called the next time the object enters the garbage collection system so such safeguards work at most once for each object.