1

When it comes to File processing and resource leaks,

what are the advantages and disadvantages between these two ways to deal with the problem:

try with resources VS Try/catch/finally with file.close?

Thanks

  • Pill
Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
Pill Beans
  • 23
  • 6

2 Answers2

3

The biggest difference is the danger of exception-masking with the try-finally approach. If you're not careful to catch anything thrown within the finally block on close, you can mask any exception thrown within the try block. That means that if the code within the try block throws an exception, then the code within the finally throws an exception, the exception that gets propagated is the one from the finally block (which is usually not the one you would want to see).

try-with-resources eliminates the danger of exception-masking by making sure that if an exception is thrown from the try block, any exception thrown by the close method gets tacked on as a suppressed exception.

The case where no exception is thrown in the try block but an exception gets thrown on close is handled differently by try-with-resources than it would be if you use try-finally and catch anything thrown in the finally block. With try-with-resources the exception thrown on close would be thrown (since there's not an exception to add it to as a suppressed exception), where the usual approach with try-finally is to eat or log any exception thrown from the finally method. So if you don't want a failure on close to cause an exception to be thrown, disrupting some logic that otherwise worked correctly, you may want to avoid try-with-resources for that.

A significant difference is how try-with-resources allows multiple resources. People writing try-finally blocks usually get impatient with nesting try blocks and cause bugs with shortcuts such as putting too many close statements in a finally block (so if one fails the remaining ones don't execute, causing a resource leak). try-with-resources guarantees closing the resources in the right order on the way out so that no nested blocks are required.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
  • 1
    I always try to use try-with-resources whenever possible, but I hate when I need to use the resource in the catch block and it is already closed, because of the change in the order of execution of close(). Never understood this design. Now, by reading this answer I get that try-with-resources-catch was never meant to be an equivalent to try-catch-finally, but to solve other problems and prevent bugs. – Gustavo Jun 06 '20 at 16:51
-1

My understanding is that

try(InputStream is = new InputStream(...)){
    ...
}

Is functionally equivalent to:

InputStream is=null;
try{
    is = new InputStream(...);
    ...
}finally{
    try{
        is.close();
    }catch(Exception e){}
}
Andreas
  • 4,937
  • 2
  • 25
  • 35
  • That's somewhere between an oversimplification and incorrect. Exceptions thrown by `close()` are not ignored. The translation of `try-with-resources` is specified [here](https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.20.3.1). – Radiodef Apr 18 '16 at 19:11