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.