Most classes will clean up their external resources in their finalize
methods, but this isn't analogous to C++'s destructor - a destructor is called as soon as an object is no longer used, but a finalizer isn't called until an object is garbage-collected, and you don't know when this is going to happen (and it might never happen if you don't have a memory-intensive program). So let's say you're allocating a bunch of objects that are each allocating a database connection (yes, you should be using connection pooling, but this is a hypothetical); you use each object and then null out its references so that it can be garbage-collected without first closing their database connections, and now your database is going to crap out on you because it's got too many connections open. You can call System.gc
in the hopes that this will clean up the connections, but this is only a suggestion to the garbage-collector that it perform a collection, and it's possible that your garbage database connections' finalizers aren't smart enough to fully clean up the connections.
Long story short, you need to call close
and shutdown
because you don't know if/when your objects' finalizers are going to run, and you don't know how good they are at cleaning up external resources.
Incidentally, you should use try-catch-finally blocks to make sure you call close
and shutdown
- put the methods in the finally block. Or if you're using Java7, use try-with-resources.