...
This noncompliant code example uses contains a finally
block that closes the reader
object. The programmer incorrectly assumes that the statements in the finally
block cannot throw exceptions, and consequently fails to handle the exception appropriately.
...
The close()
method can throw an IOException
which, if thrown, which would prevent execution of any subsequent clean-up statements. This possibility remains undiagnosed at compile time because the close()
method's throws clause specifies the same exceptions as do the throws clauses of methods read()
and write()
.
Compliant Solution (Handle Exceptions in finally
Block)
This compliant solution correctly places encloses the close()
statement method invocation in a try-catch
block of its own within the finally
block. Consequently, an IOException
can be handled without permitting it to propagate farther.
...
While suppressing a caught exception normally violates ERR00-J. Do not suppress or ignore checked exceptions, this particular code would likelybe allowed is permitted under ERR00-EX0, as the reader
would is never be accessed again, so an error in closing it can does not affect future program behavior.
...
Code Block | ||
---|---|---|
| ||
public class Operation { static void doOperation(String some_file) throws IOException { BufferedReader reader = new BufferedReader(new FileReader(some_file)); try { // Do operations } finally { closeHandlingException(reader); // Other clean-up code } } private static void closeHandlingException(BufferredReader s) { if (s != null) { try { s.close(); } catch (IOException ie) { // Forward to handler } } } public static void main(String[] args) throws IOException { doOperation("somepath"); } } |
While suppressing Suppressing a caught exception normally violates exception is again permitted under exception ERR00-EX0 of ERR00-J. Do not suppress or ignore checked exceptions, this particular code would be allowed under ERR00-EX0, as the reader
would never be accessed again, so an error in closing it can not affect future program behavior.
Compliant Solution (Java 1.7: try-with-resources)
Java 1.7 provides a new syntaxfeature, dubbed called try-with-resources, that can close certain resources automatically should an error occur. This compliant solution uses try-with-resources to properly close the file.
Code Block | ||
---|---|---|
| ||
public class Operation { static void doOperation(String some_file) throws IOException { try (BufferedReader reader = new BufferedReader(new FileReader(some_file))) { // Do operations } } public static void main(String[] args) { try { doOperation(path); } catch (IOException ex) { System.out.println("thrown exception: " + ex.toString()); Throwable[] suppressed = ex.getSuppressed(); for (int i = 0; i < suppressed.length; i++) { System.out.println("suppressed exception: " + suppressed[i].toString()); } } } } |
If an error occurs in the try
block (the Do operations
section), of the doOperation()
method it will propagate out of doOperation
, the method and be printed as the "thrown exception". If an error occurs while closing the reader
, that error will propagate out of doOperation
, ()
and be printed as the " thrown exception". But if If both errors occur, the try-block error will be the one that propagates out of the doOperation
, ()
and be printed as the " thrown exception". The close error gets is suppressed , and will be printed as the "supprssed suppressed exception". In all cases the reader
is safely closed.
Note that this example is for illustrative purposes only. Compliant code will do must perform proper exception handling, rather than simply printing exceptions to the console. For more information, see ERR00-J. Do not suppress or ignore checked exceptions.
Risk Assessment
Failure to handle an exception in a finally
block can lead to unexpected results.
...