Your interpretation is correct, try-with-resources will close only resources explicitly declared in resources block.
However, in most cases the first approach will work as well. That is because usually when some Closeable
uses another Closeable
, it will try to close it inside of its close()
method. This mechanism doesn't have anything to do with the garbage collector tho (which would just remove an object without releasing the resource).
Other than the situation where a Closeable
wouldn't close its resources, there could be other sources of resources leak in the first approach as well. Consider a following case:
try(BufferedInputStream bufferedInput = new BufferedInputStream(
new FileInputStream("file.txt"))
)
In this example, FileInputStream
will be created first. Just then it will be passed into a contructor of BufferedInputStream
. What would happen when an exception occurs during creation of BufferedInputStream
? FileInputStream
won't ever be closed.
On the other hand, when you declare those as two separate resources like so:
try(FileInputStream input = new FileInputStream("file.txt");
BufferedInputStream bufferedInput = new BufferedInputStream(input)
)
Java itself will make sure that both of the resources will be closed. The following is stated in JSL - 14.20.3.1. Basic try-with-resources :
In a basic try-with-resources statement that manages multiple resources:
If the initialization of a resource completes abruptly because of a
throw of a value V, then:
If the automatic closings of all successfully initialized resources
(possibly zero) complete normally, then the try-with-resources
statement completes abruptly because of a throw of the value V.
There are probably more cases that might cause resource leak as well.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…