9

so I have a bit of code here and I'm not sure entirely how it would react in the event that the reader.close() method throws an exception.

public void someMethod(String s) throws IOException{
   BufferedReader reader = Files.newBufferedReader(filePath,cs);
   listRWLock.readLock().lock();
   try{
     //miscellaneous code involving reading
   }finally{
     reader.close()
     listRWLock.readLock().unlock()
   }
}

ListRWLock is a ReentrantReadWriteLock. In the event that the reader.close() method throws an exception, would the statement after it fail to execute? I've tried searching for the topic, and while I've gotten something about finally executing in the event of return statements, I haven't managed to find details on what happens if an exception is thrown within the finally block.

Thanks in advance.

ElvenAshwin
  • 183
  • 1
  • 7
  • 1
    The subsequent statements should not execute. Also, `return` in `finally` block can override previous exceptions. – S.D. Sep 28 '14 at 05:17

4 Answers4

4

Basically, finally clauses are there to ensure proper release of a resource. However, if an exception is thrown inside the finally block, that guarantee goes away.

An issue for which there's no really neat solution is that code in the finally block could itself throw an exception. In this case, the exception in the finally block would be thrown from the exception instead of any exception occurring inside the try block. Since code in the finally block is intended to be "cleanup" code, we could decide to treat exceptions occurring there as secondary, and to put an excplicit catch:

public int readNumber(File f) throws IOException, NumberFormatException {
  BufferedReader br = new BufferedReader(new
    InputStreamReader(new FileInputStream(f), "ASCII"));
  try {
    return Integer.parseInt(br.readLine());
  } finally {
    try { br.close(); } catch (IOException e) {
      // possibly log e
    }
  }
}

Some other things to note about finally blocks:

  1. The same 'overriding' problem that we mentioned with exceptions occurs when returning a value from a finally block: this would override any return value that the code in the try block wanted to return. In practice, returning a value from a finally clause is rare and not recommended.
  2. Actually exiting the program (either by calling System.exit() or by causing a fatal error that causes the process to abort: sometimes referred to informally as a "hotspot" or "Dr Watson" in Windows) will prevent your finally block from being executed!
  3. There's nothing to stop us nesting try/catch/finally blocks (for example, putting a try/finally block inside a try/catch block, or vice versa), and it's not such an uncommon thing to do.
Pert8S
  • 582
  • 3
  • 6
  • 21
  • You have directly copied and mish mashed your answer from [here](http://www.javamex.com/tutorials/exceptions/exceptions_finally.shtml) and [here](http://softwareengineering.stackexchange.com/a/188877/114810) ? Taking one sentence from each of them! Have the decency to at least give them credit! – Kumar Manish Feb 22 '17 at 19:05
4

You can do something like this:

try{
    //miscellaneous code involving reading
}finally{
   handlePossibleException(reader);
   listRWLock.readLock().unlock()
}

handlePossibleException(BufferedReader reader) {
    try {
         if (reader != null) {
             reader.close();
         }
    } catch( Exception e ) {
      log.e( "reader.close() Exception: ", e );
      }
} 
Vikas
  • 4,263
  • 1
  • 34
  • 39
1

You should test this,

but if try throws IO Exception, then your reader wont close.

Maybe have

catch(IOException ex){ 
         reader.close()
smushi
  • 701
  • 6
  • 17
1

An exception can happen anywhere in your code, including finally block, so you have to catch it as anywhere else in your code. Check the following post to get some ideas about the ways you can handle such situation:

throws Exception in finally blocks

Community
  • 1
  • 1
zaerymoghaddam
  • 3,037
  • 1
  • 27
  • 33