Well you've given a bad example - I suspect you meant something like FileInputStream
- but the basic reason is that Java doesn't have deterministic finalization.
The scope of the variable f
ends with the block it's declared in (not the try
block), but that doesn't mean there are necessarily no "live" references to the object any more - and the garbage collector will neither finalize the object nor garbage collect it in any deterministic manner.
Unless you want to leave resources hanging around for an arbitrary length of time (and delay garbage collection, as finalizers require an extra round of collection before the memory is finally released), you should explicitly close resources.
Basically Java does not support RAII in the same way that C++ does; you shouldn't try to use it as if it were C++.