Java try with resources – J043

by | Mar 30, 2016




DeegeU Java Course

The “Java Try with Resources” video is part of a larger free online class called “Free Java Course Online”. You can find more information about this class on “Free Java Course Online” syllabus.

Transcript – Java Try with Resources

In this video, we’re going to look at the try-finally, and the try with resources statements! Coming up next!

There are times when we want to make sure something happens in our code no matter what. If an exception happens, we need the code to run. If an exception doesn’t happen, we still want the code to run. An example of this is when we open a file. If there’s an exception, we want to make sure the file is close. If there is no exception, we still want the file closed.

Let’s take a look at this code. Imagine if we want to open a file, and do things in the file. Since a file might not be there, exceptions can be thrown.

String line = null; 
FileReader fileReader = new FileReader("test.txt"); 
BufferedReader bufferedReader = new BufferedReader(fileReader);

while((line = bufferedReader.readLine()) != null) {
    System.out.println(line);
}

That means we need to catch the exceptions, so we’ll wrap the important bits with a try-catch. We also want to close the file when we’re done. Otherwise we will leak resources.

The first thought might be to just add a statement to close the file here. This won’t work. The reason is we’ll never get to this line. An exception might get thrown on an earlier line of code, and then we’ll skip to the catch block. Our file never gets closed, and we are leaking file resources.

String line = null; 

try {
    FileReader fileReader = new FileReader("test.txt"); 
    BufferedReader bufferedReader = new BufferedReader(fileReader);

    while((line = bufferedReader.readLine()) != null) {
        System.out.println(line);
    }

    fileReader.close();
    bufferedReader.close();
} catch (FileNotFoundException fe) {
    // handle exception
}

The next thought might be to close the file in the catch block, but that’s duplicating code. Not a good idea. In Java, the finally block is used to prevent resource leaks like the one we see here.

We add it to a try statement like this. In this code, we try a block of statements. After those run successfully, the finally block is executed.

String line = null; 

try {
    FileReader fileReader = new FileReader("test.txt"); 
    BufferedReader bufferedReader = new BufferedReader(fileReader);

    while((line = bufferedReader.readLine()) != null) {
        System.out.println(line);
    }

} catch (FileNotFoundException fe) {
    // handle exception
} finally {
    fileReader.close();
    bufferedReader.close();
}

If there is an exception in the try block, the catch block is run for a matching exception. And then the finally is executed. In both cases, the finally is always run. That’s where we want to close our file. One problem, fileReader is defined in the try block and we’re trying to close it in the finally block. We need to fix that.

This moves the object definitions outside of the try block. Now they can be used in the finally. Of course they might be null when we try to close them.

So we need to check to make sure the objects are null before trying to close them. This is getting pretty lengthy.

String line = null; 
FileReader fileReader = null;
BufferedReader bufferedReader = null;

try {
    fileReader = new FileReader("test.txt"); 
    bufferedReader = new BufferedReader(fileReader);

    while((line = bufferedReader.readLine()) != null) {
        System.out.println(line);
    }

} catch (FileNotFoundException fe) {
    // handle exception
} finally {
    if (fileReader != null) {
        fileReader.close();
    }
    if (bufferedReader != null) {
        bufferedReader.close();
    }
}

This is the way it’s been handled up to Java 7. There’s still a problem with this. Closing a file in Java uses a statement that throws an exception. This means in our catch, we have the possibility of throwing another exception.

We need another try-catch in our catch! And we’ll lose all the information that got us here in the first place. That’s no good. Luckily the folks making Java realized this, and added the try with resources statement.

In Java 7, any object that implements AutoClosable can be used in the try with resources statement. That’s pretty much anything in Java with a close method. This is the list of all the Java classes we can use with the try with resources. You can see this list in the Java documentation for the AutoClosable interface. Some third party classes also implement this interface, but you’ll have to check your documentation.

String line = null; 

try ( FileReader fileReader = new FileReader(“test.txt”);
      BufferedReader bufferedReader = new BufferedReader(fileReader);
    ) {

    while((line = bufferedReader.readLine()) != null) {
        System.out.println(line);
    }

} catch (FileNotFoundException fe) {
    // handle exception
} finally {
    try {
        if (fileReader != null) {
            fileReader.close();
        }
        if (bufferedReader != null) {
            bufferedReader.close();
        }
    } catch (Exception e) {
         System.out.println(e);
    }
}

So what does this buy us? Well the syntax for the try with resources allows us to create one or more objects as part of the try statement. That looks like this. We don’t need to define the variable outside of the try block. When we define it like this, the variable is available for the whole try block. That’s neat, but here’s where the real magic happens.

The class implements AutoClosable. The try with resources statement knows this. We don’t need to tell Java to close our file. The entire finally statement goes away, not just the closing try-catch. We can’t forget calling close either. It’s automatic.

String line = null; 

try ( FileReader fileReader = new FileReader(“test.txt”);
      BufferedReader bufferedReader = new BufferedReader(fileReader);
    ) {

    while((line = bufferedReader.readLine()) != null) {
        System.out.println(line);
    }

} catch (FileNotFoundException fe) {
    // handle exception
}

We can still have the catch and finally statements if we need them, but we should never need the finally to close resources. That’s 90% of the time you’d need to use the finally. In fact, you might find moving an old Java application to Java 7 or later will remove all the finally statements in your code.

The try with resources can also handle multiple resources. The same thing happens in this case. Both variables are for use within the try block, and both are closed automatically. If you need one resource as an input for another resource, you can do that like this.

I hinted earlier that try with resources works with classes outside the core Java classes. That’s true for classes we create as well. If we need to have a close method in a class we create, we can implement AutoClosable and get all the benefits of the try with resources statement. Users of our class can’t forget to call close. It’s win-win.

That concludes the try statement.

If you have any questions, add them to the comments below. Liking the video helps me know what I’m doing right, so if you liked the video… you know what to do.

And with that, I’ll see you in the next tutorial!







Related Posts

Tools Used

  • Java
  • NetBeans

Media Credits

All media created and owned by DJ Spiess unless listed below.

  • No infringement intended

Get the code

The source code for “Java Try with Resources” can be found on Github. If you have Git installed on your system, you can clone the repository by issuing the following command:

 git clone https://github.com/deege/deegeu-java-intro.git

Go to the Support > Getting the Code page for more help.

If you find any errors in the code, feel free to let me know or issue a pull request in Git.

Don't miss another video!

New videos come out every week. Make sure you subscribe!

Comments

comments

DJ Spiess

DJ Spiess

Your personal instructor

My name is DJ Spiess and I’m a developer with a Masters degree in Computer Science working in Colorado, USA. I primarily work with Java server applications. I started programming as a kid in the 1980s, and I’ve programmed professionally since 1996. My main focus are REST APIs, large-scale data, and mobile development. The last six years I’ve worked on large National Science Foundation projects. You can read more about my development experience on my LinkedIn account.

Pin It on Pinterest

Share This