...
| Code Block | ||
|---|---|---|
| ||
public class Operation {
public static void doOperation(String some_file) throws IOException {
BufferedReader reader = null;
// ... code to check or set character encoding ...
try {
BufferedReader reader = new BufferedReader(new FileReader(some_file));
try //{
Do operations
} finally// {
Do operations
if (reader !=} null)finally {
reader.close();
}
// ... Other clean-up code ...
}
} catch (IOException x) {
// Forward to handler
}
}
}
|
The close() method can throw an IOException which, if thrown, would prevent execution of any subsequent clean-up statements. The compiler will correctly fail to diagnose this problem because the doOperation() method explicitly declares that it may throw IOException IOException}}s are caught by the outer catch block. Also, an exception thrown from the {{close() operation can also mask any exception that gets thrown during the Do operations section, preventing proper recovery.
Compliant Solution (Handle Exceptions in finally Block)
...
| Code Block | ||
|---|---|---|
| ||
public class Operation {
public static void doOperation(String some_file) throws IOException {
BufferedReader reader = null;
// ... code to check or set character encoding ...
try {
BufferedReader reader = new BufferedReader(new FileReader(some_file));
// Do operationstry {
} finally {
// if (reader != null) {Do operations
} tryfinally {
// Enclose in try-catch block{
reader.close();
} catch (IOException ie) {
// Forward to handler
}
}
// Other clean-up code
}
}
}
|
...
. |
...
. |
...
Compliant Solution (Dedicated Method to Handle Exceptions)
When closing a stream without throwing an exception is a frequent pattern in the code, an alternative solution is to use a closeHandlingException() method, as shown in this compliant solution.
| Code Block | ||
|---|---|---|
| ||
public class Operation { public static void doOperation(String some_file) throws IOException { BufferedReader reader = null; // ... code to check or set character encoding ... try { reader = new BufferedReader(new FileReader(some_file)); // Do operations } finally { closeHandlingException(reader); // Other clean-up code ... } } private static void closeHandlingException(Closeable c) { if (c != null) { try { c.close(); } catch (IOException iex) { // Forward to handler } } } } |
Compliant Solution (Java 1.7: try-with-resources)
...
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="90cf87fec91c31d9-b4b64410-41c846ed-bf87ba2c-4b6a1b0861e96585ca9c57b3"><ac:plain-text-body><![CDATA[ | [[Bloch 2005 | AA. Bibliography#Bloch 05]] | Puzzle 41: Field and Stream | ]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="a3f2c389ee550afc-7f7c3048-432b4915-8ba8b1be-4801210706eecaa66d424d0d"><ac:plain-text-body><![CDATA[ | [[Chess 2007 | AA. Bibliography#Chess 07]] | 8.3 Preventing Resource Leaks (Java) | ]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="d03d84ea6d98114f-b53e43e3-45a44a80-b174ad65-7d669db24da704842ced29d4"><ac:plain-text-body><![CDATA[ | [[Harold 1999 | AA. Bibliography#Harold 99]] |
| ]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="3067639f71374053-815e458b-4aa743f1-bea7b81b-8079620f17587be454fc1d6e"><ac:plain-text-body><![CDATA[ | [[J2SE 2011 | AA. Bibliography#J2SE 11]] | The try-with-resources Statement | ]]></ac:plain-text-body></ac:structured-macro> |
...