0

I came around to a piece of code for Base64 encoding. While reading it I stumbled upon something like this:

    try {
      // GZip -> Base64 -> ByteArray
      baos = new java.io.ByteArrayOutputStream();
      b64os = new OutputStream( baos, ENCODE | options );
      gzos  = new java.util.zip.GZIPOutputStream( b64os );

      gzos.write( source, off, len );
      gzos.close();


    }   // end try
    catch( java.io.IOException e ) {
      // Catch it and then throw it immediately so that
      // the finally{} block is called for cleanup.
      throw e;
    }   // end catch
    finally {
      try{ gzos.close();  } catch( Exception e ){}
      try{ b64os.close(); } catch( Exception e ){}
      try{ baos.close();  } catch( Exception e ){}
    }   // end finally

As you see the IOException is caught in a catch Block and immediately rethrown and it does not seems to be a mistake, because the comment even describes the action and names the execution of the finally block as the purpose.

But wouldn't the finally block be called anyway?

Sources:

Base64-De/Encoder (Public Domain) (Author: Robert Harder)

Tash Pemhiwa
  • 7,590
  • 4
  • 45
  • 49
dertoni
  • 1,763
  • 2
  • 24
  • 47
  • 1
    Because the person who wrote that code didn't want to handle that `IOE`. Rather, they wanted the caller of this method to handle the exception, for reasons better known to them. – Rahul Jun 13 '14 at 11:13
  • But then why catch it at all? – dertoni Jun 13 '14 at 11:14
  • 10
    Because the person who wrote that code didn't know that you can have a finally block without catch block. There should not be a catch block here: it's useless, and even harmful because it loses the actual line where the original exception was thrown. Closing all the streams in the finally block is also useless, since closing the top-evel one will close the other ones. – JB Nizet Jun 13 '14 at 11:14
  • Reading catch block comment - "then throw it immediately so that the finally{} block is called for cleanup." Even if you dont throw the exception again, or in anycase the finally block will be called whatsoever. – Mustafa sabir Jun 13 '14 at 12:33

1 Answers1

0

There are cases where you might want to catch and rethrow an exception. Logging, cleaning up local resources known only to the code where the exception is generated, could be some of the reasons.

Exception will continue to bubble up through the layers until it reaches some other code that catches it and does not re-throw it or otherwise it will reach the top of exception stack and program can exit by reporting the exception.

In your code above, As you don't want to handle the exception at your layer, there are some resources like gzos, baos, b64os which needs to be freed before you throw the exception again to the higher layers. once you catch and re-throw, your finally block can execute and cleanup the held resources.

Sometimes you might also want to wrap up the exception with more information. for example:

public void function() throws BaseException {
    try {
      ....
    } catch (IOException e) {
         throw new BaseChildException(e) // BaseChildException is a subclass of BaseException
    }
}
Ankit Kumar
  • 1,433
  • 1
  • 16
  • 24