...
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="b409873e7c81ed90-8efb42e6-426b4273-846e8a2f-c08ff2719d945941232d29c8"><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="b56aa17c1ca8c2c0-08cf1f02-416f4273-a5b3bfcd-281518ef17946efa2f018cb3"><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="3b623967397527da-42c627ef-43464aa0-bf2e9470-e072339a6b2c1f3331001976"><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="ed12be97a58ebf6b-afd21436-44ff41cf-9bbea5c3-617b0ffc73bae8c8ec96cc30"><ac:plain-text-body><![CDATA[ | [[J2SE 2011 | AA. Bibliography#J2SE 11]] | The try-with-resources Statement | ]]></ac:plain-text-body></ac:structured-macro> |
...