Alex Rivera | Logout

Is there a preference for nested try/catch blocks?

Asked 2008-10-08T15:53:32.520
41

One of the things that always bugs me about using Readers and Streams in Java is that the close() method can throw an exception. Since it's a good idea to put the close method in a finally block, that necessitates a bit of an awkward situation. I usually use this construction:

FileReader fr = new FileReader("SomeFile.txt");
try {
    try {
        fr.read();
    } finally {
        fr.close();
    }
} catch(Exception e) {
    // Do exception handling
}

But I've also seen this construction:

FileReader fr = new FileReader("SomeFile.txt");
try {
    fr.read() 
} catch (Exception e) {
    // Do exception handling
} finally {
    try {
        fr.close();
    } catch (Exception e) {
        // Do exception handling
    }
}

I prefer the first construction because there's only one catch block and it just seems more elegant. Is there a reason to actually prefer the second or an alternate construction?

UPDATE: Would it make a difference if I pointed out that both read and close only throw IOExceptions? So it seems likely to me that, if read fails, close will fail for the same reason.

Edit
Report

2 Answers

0

2nd approach.

Otherwise, I don't see you catching the exception from the FileReader constructor

http://java.sun.com/j2se/1.5.0/docs/api/java/io/FileReader.html#FileReader(java.lang.String)

public FileReader(String fileName) throws FileNotFoundException

So, I usually have the constructor inside the try block as well. the finally block checks to see if the reader is NOT null before trying to do a close.

The same pattern goes for Datasource, Connection, Statement, ResultSet.

answered 2008-10-08T17:58:32.143
0

I like the approach by @Chris Marshall, but I never like to see exceptions getting swallowed silently. I think its best to log exceptions, especially if you are contiuing regardless.

I always use a utility class to handle these sort of common exceptions, but I would make this tiny different to his answer.

I would always use a logger (log4j for me) to log errors etc.

IOUtil.close(fr);

A slight modification to the utility method:

public static void close(Closeable c) {
    try {
      c.close();
    } catch (Exception e) {
      logger.error("An error occurred while closing. Continuing regardless", e); 
    } 
}
answered 2008-10-08T23:43:56.437

Your Answer