5

In new, third edition of Effective Java Joshua Bloch mentions piece of code from Java Puzzlers (it's about closing resources in try-finally):

For starters, I got it wrong on page 88 of Java Puzzlers, and no one noticed for years. In fact, two-thirds of the uses of the close method in the Java libraries were wrong in 2007.

But I am not sure which part is wrong here?

} finally {
  if (in != null) {
    try {
      in.close();
    } catch (IOException ex) {
      // There is nothing we can do if close fails
    }
  }
  if (out != null) {
    try {
      out.close();
    } catch (IOException ex) {
      // Again, there is nothing we can do if close fails
    }
  }
}

This is new version of this code:

try {
  OutputStream out = new FileOutputStream(dst);
  try {
    byte[] buf = new byte[BUFFER_SIZE];
    int n;
    while ((n = in.read(buf)) >= 0) out.write(buf, 0, n);

  } finally {
    out.close();
  }
} finally {
  in.close();
}
ctomek
  • 1,696
  • 16
  • 35
  • 3
    These days the new version is wrong too. In general, we should use `try-with-resources` instead. `try-with-resources` has more comprehensive handling when multiple exceptions are thrown. For example, in Bloch's second example, if both `in.close()` and `out.close()` throw an exception, the one thrown from `out.close()` will be lost forever, but `try-with-resources` [adds it to the suppressed exceptions](https://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html#addSuppressed-java.lang.Throwable-). https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html – Radiodef Jan 25 '18 at 18:00
  • 2
    @Radiodef Yes, try-with-resources is a recommended solution, I just wanted to make sure what was wrong in this pre try-with-resources world. – ctomek Jan 25 '18 at 18:02

1 Answers1

11

If in.close() throws an exception not caught by the catch block (such as any RuntimeException), out won't be even tried to be closed.

While in the given example (with normal streams where IOException would be most likely) it's not a huge issue, the code is not correct and learning to write it like that could cause more serious issues down the road.

Kayaman
  • 72,141
  • 5
  • 83
  • 121