Java try-finally inside try-catch pattern
Whenever I need to acquire a resource in Java and then guarantee that the resource is released, where an exception might be thrown, I use the following pattern:
try {
Resource resource = null;
try {
resource = new Resource();
// Use resource
} finally {
if (resource != null) {
// release resource
}
}
} catch (Exception ex) {
// handle exceptions thrown by the resource usage or closing
}
For example, if I need a database connection, and using or closing the connection can throw an excep开发者_C百科tion, I write the following code:
try {
Connection connection = null;
try {
connection = ... // Get database connection
// Use connection -- may throw exceptions
} finally {
if (connection != null) {
connection.close(); // This can also throw an exception
}
}
} catch (SQLException ex) {
// handle exceptions thrown by the connection usage or closing
}
I don't like just doing a simple try-catch-finally because I am obligated to catch the (possible) exception that can be thrown when the database connection is closed, and I am never sure how to handle that one.
Is there a better pattern for handling this situation?
Personally, I use the following pattern:
Connection connection = null;
try {
connection = ... // Get database connection
// Use connection -- may throw exceptions
} finally {
close(connection);
}
private void close(Connection connection) {
try {
if (connection != null) {
connection.close(); // This can also throw an exception
}
} catch (Exception e) {
// log something
throw new RuntimeException(e); // or an application specific runtimeexception
}
}
or similar to that. This pattern doesn't lose the exception, but makes your code a lot cleaner. I use this pattern when the exception being caught in the finally clause (in this case close()) is difficult to deal with and should be dealt with at a higher level.
Cleaner still is to use the loan pattern.
IOUtils.closeQuietly()
could solve your problem.
Example:
Closeable closeable = null;
try {
closeable = new BufferedReader(new FileReader("test.xml"));
closeable.close();
} catch (IOException e) {
// Log the exception
System.err.println("I/O error");
} finally {
// Don't care about exceptions here
IOUtils.closeQuietly(closeable);
}
You should not catch exceptions if you don't know how to handle them.
精彩评论