Let’s do Exception handling.
Sometimes we want to handle different types of exception the same way, to have more control and details on the type of error our program runs into.
The old exception multi-catch handling style is:
try {
// access the database and write to a file
} catch (SQLException e) {
handleErrorCase(e);
} catch (IOException e) {
handleErrorCase(e);
}
Exception multi-catch handling
From the Java 7 and later version we can handle more Exception types on the same line, with a pipe how “OR”:
try {
// access the database and write to a file
} catcha (SQLException | IOException e) {
handleErrorCase(e);
}
Pay attention to some important things:
- You can’t declare more than one exception variables in a single multi-catch:
catch (Exception1 e1 | Exception2 e2) // not compiles!
catch (Exception1 e | Exception2 e) // not compiles!
- You can’t declare two exceptions in the same inheritance tree:
catch (IOException | FileNotFoundException e) /* not compiles
because FileNotFoundException is a subclass of IOException! */
- With single catch the variable assignment works but not the new one:
catch (IOException e) {
e = new IOException(); // works!
}
...
catch (SQLException | IOException e) {
e = new IOException(); // not compiles!
}
Rethrowing Exceptions
This is a common pattern called “handle and declare”.
When you have to do something with the exception – log it.
public void rethrow() throws SQLException, IOException {
try {
couldThrowAnExceptionMethod();
} catch (Exception e) { // this isn't really catching all exception subclasses
log(e);
throw e; // won't compile in Java 6
}
]
We declare that exception and let the caller deal with it.
Note that we aren’t really catching all exceptions. The compiler is treating Exception as “any exceptions that the called methods happen to throw”, from Java 7 and later.
Finally and try-with-resources
Before Java 7 to force close a connection, when something went wrong we used block finally:
try {
return br.readLine();
} finally {
br.close();
fr.close();
}
From 7 onwards, however, it is possible to avoid this closing rite, using an ad hoc syntax for that type of connection, the try-with-resources
block:
try (FileReader fileReader = new FileReader(path); BufferedReader br = new BufferedReader(fileReader)) {
return br.readLine();
}
To call itself a “resource”, it must implement java.lang.AutoCloseable (with all objects implementing java.io.Closeable). This allows him to have the necessary tools to automatically close access to a file system or connection to a DB, depending on the resource being called.
That’s all for today, without exceptions.
Try it at home!