0

Code Snippet :

InputStream inputStream = null;
try{
    ExternalServiceObject object = externalService.getObject();
    inputStream = object.getInputStream();
    // further uses of inputStream
 } catch(Exception e){
   throw e;
  } finally {
        if(inputStream != null)
           inputStream.close();
  }

Here, externalService.getObject() can also throw an exception.

Wish to refactor this code using try-with-resources, hence avoiding the finally block. Or is the current behavior the most appropriate behavior.

All the comments and answers are appreciated.

Kartavya Ramnani
  • 800
  • 9
  • 17
  • 2
    If your question is about whether exception thrown inside resource declaration part of `try-with-resources` will be handled, then the answer is yes. You can try it with a relatively simple example - make your `externalService.getObject()` throw some exception and check whether `catch` block is executed. – Igor Nikolaev Jan 05 '18 at 22:17
  • Yes, That is part of the question. Helped me understand try-with-resources. Thanks Much. – Kartavya Ramnani Jan 05 '18 at 22:24

4 Answers4

4

If you don't need the external service object for anything else:

try (InputStream inputStream = externalService.getObject().getInputStream()) {
    // further uses of inputStream
} catch (Exception e) {
    // ... logging etc
    throw e;
}
AJNeufeld
  • 8,526
  • 1
  • 25
  • 44
3

I believe that execution order in the try-with-resources is top-down (like all other java variable definitions)

try
(
    ExternalServiceObject externalServiceObject = externalService.getObject(),
    InputStream inputStream = externalServiceObject.getInputStream();
)
{
    // further uses of inputStream
}
catch (Exception e)
{
    // do stuff.
}

Caveat: ExternalServiceObject must implement AutoCloseable

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
DwB
  • 37,124
  • 11
  • 56
  • 82
2

So, use try-with-resources if that's what you want to use:

try {
  ExternalServiceObject object = externalService.getObject();
  try (InputStream inputStream = object.getInputStream()) {
    // ...
  }
} catch (Exception e) {
  throw e; // But why catch it only to rethrow?
}
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
1

The closing of the InputStream can be done using a try-with-resources block. It is more readable and less clunky. InputStream implements AutoCloseable and thus upon exiting a try-with-resources block the class's close method will automatically be called. If you are only using the InputStream for the scope of the try-catch-finally block then you should move it to the try block.

Also, you should avoid (where possible) catching Exception. Any resulting exceptions that are thrown in your try block could result in unwanted behavior.

SirCipher
  • 933
  • 1
  • 7
  • 16