Finalize on Fail

Categories: Java

Another interesting quirk of Java : if a class has a finalize() method, then that will be invoked on an object even if the constructor throws an exception!

I found this out by accident: I subclassed FileInputStream and overrode method close() to do some extra cleanup. But: has a finalize() method, and this calls close(). Therefore my close method gets invoked even when the file was never successfully opened! And just to make things more interesting, FileInputStream and its ancestors provide no way of checking whether the input-stream is open.

Interestingly, the close() method normally gets called twice for a FileInputStream:

  • once when the using code explicitly closes it (using a try-with-resources or a finally clause).
  • again when the finalizer runs.

And again, the ancestor classes provide no way to query whether the stream is still open; InputStream.close() uses a private boolean to track this, but does not provide any way to access that. Working around this problem is not too complex, but the standard behaviour is far from intuitive..