Concise try-with-resources Statement – Exception Handling

Concise try-with-resources Statement

The header of the try-with-resources statement can be made less verbose by factoring out the resource declarations from the header. This refactoring involves declaring the resources preceding the try statement and specifying instead the resource variables in the header. The resources must be AutoCloseable (to provide the close() method) as before, but in addition must also be either final or effectively final to ensure that the right resource is closed.

Click here to view code image

final ACResource1 acr1 = new ACResource1();     // (1)
ACResource2 acr2 = new ACResource2();           // (2) Effectively final at (3)
// …
try (acr1; acr2) {                              // (3) Resource variables.
  // Use the resources.
} // Both resources closed on exit.

The variable names of the AutoCloseable resources declared at (1) and (2) are specified in the header of the try-with-resources statement at (3). Apart from the syntactic difference, the semantics of the try-with-resources statement are not changed in any way. The resources acr1 and acr2 are guaranteed to be closed no matter how the execution of the try statement at (3) proceeds.

However, care must be taken if any resource declarations proceeding the try-with-resources statement can throw exceptions. For example, if the declaration of acr2 at (2) above throws an exception, the execution will be interrupted and the resource acr1 created at (1) will not be closed—leading to resource leakage. One solution is to move the declaration of acr2 into the header of the try-with-resources statement as shown below at (3). The list in the header can be a mix of resource variables and resource declarations. This setup will ensure that both resources will be closed regardless of how the execution in the try statement proceeds. The try-with-resources statement can be augmented with the necessary catch blocks to catch any exceptions thrown during its execution, as shown at (4).

Click here to view code image

final ACResource1 acr1 = new ACResource1();              // (1)
// …
try (acr1; ACResource2 acr2 = new ACResource2()) {       // (3)
  // Use the resources.
} catch (Exception ex) {                                 // (4)
  ex.printStackTrace();
} // Both resources closed on exit.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *