Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

try-with-resources details [duplicate]

Tags:

java

Working with objects we use 3 basic steps:

  1. Declaration
  2. Instantiation
  3. Initialization

And my question is about what steps must be done in () part of try-with in order auto close on resource to be made.

Example 1 - will FileReader object be auto closed in this code:

try (BufferedReader br = new BufferedReader(new FileReader(filePath)))
{
//some code;
} 

Example 2 - will the buf2 be auto closed in this code:

private static BufferedReader buf1;

public static void main(String[] args) throws IOException {
    //some code
    try (BufferedReader buf2 = buf1)
    {

    } 
 }

P.S. Someone supposes that this question is duplicate of Try With Resources vs Try-Catch . It is not. That question is about difference between try-catch and try-with-resources. My question is about details of try-with.

like image 940
Pavel_K Avatar asked Feb 09 '23 03:02

Pavel_K


1 Answers

Whenever language related details are needed, the most complete reference is the Java Language Specification (just Google it). For the try-with-resources statement, you can read section 14.20.3 which states that the following:

try ({VariableModifier} R Identifier = Expression ...)
    Block

is translated to

{
   final {VariableModifierNoFinal} R Identifier = Expression; 
   Throwable #primaryExc = null;
   try ResourceSpecification_tail
      Block catch (Throwable #t) {
         #primaryExc = #t;
         throw #t;
      } finally {
         if (Identifier != null) {
            if (#primaryExc != null) { 
               try { 
                  Identifier.close(); 
               } catch (Throwable #suppressedExc) { 
                  #primaryExc.addSuppressed(#suppressedExc);
               }
            } else {
               Identifier.close();
            }
         }
     }
}

In your first example, the resource R is BufferedReader, the Identifier is br and the Expression is new BufferedReader(new FileReader(filePath)). It follows that only the BufferedReader is closed in the implicit finally block. The finally block will not call close on the FileReader because it is not part of the resource declaration itself. However, it happens that the implementation of BufferedReader.close() internally calls the close method of the wrapped FileReader. So the answer to the first question is yes simply because the wrapper object closed it (following the common wisdom that a resource should release any wrapped resource when being itself released), not because of the try-with-resources.

In the second example:

private static BufferedReader buf1;

public static void main(String[] args) throws IOException {
    //some code
    try (BufferedReader buf2 = buf1)
    {

    } 
}

the answer depends on the some code. Here buf2 and buf1 both refer to the same object in memory. If this "some code" initializes buf1 to some object, then this object will be closed since buf2 also refers to it. If not and buf1 is null (and therefore buf2 is null), then nothing will be closed because of the null check in the implicit finally shown above.

like image 108
M A Avatar answered Feb 11 '23 17:02

M A