Java's try with resources
Introduction
If you’ve written some Java, you must be familiar with Java’s streams. These streams include InputStream
and OutputStream
for reading and writing binary data and Reader
, Writer
classes for reading and writing character streams. We will look at the main points of Java streams, which are handling exceptions and closing them.
Managing streams
The streams mentioned above are likely to fail and when they to they throw an IOException
. So, a sample code for reading from readable stream would be like this:
InputStream inputStream = // some input stream |
All readable streams include int read()
and int read(byte[] buff)
methods. As the name suggests they help us to read from the stream and return bytes that are read from. If returned values is less than 0 (zero) then the stream is ended. Since the InputStream
is for reading binary data, we also cast the integer value to byte
.
Now, the above code is somehow complete, but ignores an important point: the stream is not closed after reading from it. We can close it in try-catch’s finally
block. However, since the closing the stream also contains some checking and may throw an IOException
, the code will look something like this:
InputStream inputStream = // some input stream |
This is a lot of code, isn’t it? :) To simplify such scenarios we use Java’s try with resources.
The AutoClosable interface
The reason why streams expose a void close() throws IOException
method, because they implement an interface called Closable
interface. Closable
interface extends an interface named AutoClosable
interface which gives them void close() throws Exception
method and makes them close automatically when used inside a try-with resorces block. Now, what’s try-with resources? I believe, you may have seen them. We can modify the above code like so:
// resource is automatically closed because |
The parentheses after try
contains a resource and the resource is being closed automatically after the code block finishes executing. The good news is you don’t have to write that messy code we write earlier.
To prove that the resource is always being closed, let’s do some little experiment. Let’s create out own class that implements AutoClosable
interface and use it inside a try-with resources block.
class ExampleStream implements AutoCloseable { |
This is our AutoClosable, let’s use it:
try (ExampleStream exampleStream = new ExampleStream()) { |
If you run this example on your own, you will see it printing I am doing something...
and then I am being closed.
like so. This proves that try-with resources calls void close() throws Exception
method of the resource. There are lots of real life use cases but to show one, let’s read a file using BufferedReader
class:
try (BufferedReader reader = Files.newBufferedReader(Paths.get("data.txt"))) { |
BufferedReader
extends abstract Reader
class, which implements Closable
(remember: Closable
interface extends AutoClosable
interface). So, the read stream is being closed after the code finishes executing :)
Conclusion
Thanks for reading!
If you find any mistakes in any of my articles, please do not hesitate to fix them and send me a PR.
https://github.com/orkhan-huseyn/my-blog
This article contains some concepts discussed in Java Fundamentals: The Core Platform course in Pluralsight.