If I have a class that utilizes an IO resource, such as a disk flat file, DB, or some other form of external resource, what are pros and cons of closing those streams/connections in an overridden finalize() method to be run by GC? I though this could leverage the existing JVM GC and reduce the exposure to the risk of relying on the client to invoke a class method called something like closeResources() as well as writing spaghetti-like try-catches (nested try-catches and ifs being my least favorite programming constructs).
As a concrete example, I have a simple file reading wrapper. The class is constructed with String filePath, it reads the file into a List<String[]> . I don’t wan’t to have to close the BufferedReader in multiple places like close it if there is a problem opening the file (catch clause) but also close it if the file reads fine etc. I want to put it in one place and make sure it is ALWAYS closed no matter what when the object gets GC.
Is this approach a good practice or am I trying to afford myself too high level a convenience within the scope of Java?
This is not a great idea as the
finalize()method is not guaranteed to be called.It’s easier and better to just close the resources when your code is done with them.
If you hate writing the nested try-finally blocks to close the resources correctly, use something like commons-io’s IOUtils to silently close the resources (or write your own simple util method to silently close them):