Menu
Coddy logo textTech

Try With Resources Pattern

Part of the Object Oriented Programming section of Coddy's Java journey — lesson 62 of 87.

When working with resources like file streams or database connections, you must always close them when finished—otherwise you risk memory leaks. The traditional approach uses a finally block, but it's verbose and error-prone.

Java's try-with-resources statement automatically closes resources when the block completes. Any class that implements the AutoCloseable interface can be used with this syntax:

// Traditional approach - verbose and risky
BufferedReader reader = null;
try {
    reader = new BufferedReader(new FileReader("file.txt"));
    String line = reader.readLine();
} finally {
    if (reader != null) {
        reader.close();  // Could also throw an exception!
    }
}

// Try-with-resources - clean and safe
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
    String line = reader.readLine();
}  // Automatically closed here

You can manage multiple resources by separating them with semicolons. They're closed in reverse order of declaration:

try (FileReader fr = new FileReader("input.txt");
     BufferedReader br = new BufferedReader(fr)) {
    // Use both resources
}  // br closed first, then fr

To create your own auto-closeable class, implement the AutoCloseable interface and its single close() method:

public class DatabaseConnection implements AutoCloseable {
    public DatabaseConnection() {
        System.out.println("Connection opened");
    }
    
    @Override
    public void close() {
        System.out.println("Connection closed");
    }
}

This pattern ensures resources are always properly released, even if exceptions occur during processing.

challenge icon

Challenge

Easy

Let's build a resource management system that demonstrates the power of try-with-resources! You'll create custom auto-closeable classes that simulate managing connections and sessions, ensuring they're always properly cleaned up.

You'll organize your code across three files:

  • Connection.java: Create a class that simulates a database connection. Your Connection class should implement AutoCloseable. It needs a private field for the connection name (String), a constructor that takes the name and prints [name] connection opened, a query(String sql) method that prints Executing on [name]: [sql], and the required close() method that prints [name] connection closed.
  • Session.java: Create another auto-closeable class that simulates a user session. Your Session class should also implement AutoCloseable. Include a private field for the username (String), a constructor that takes the username and prints Session started for [username], a performAction(String action) method that prints [username] performed: [action], and a close() method that prints Session ended for [username].
  • Main.java: Bring your resource management system together! You'll receive three inputs: a connection name, a username, and an action to perform.

    First, demonstrate single resource management. Print === Single Resource ===, then use try-with-resources to create a Connection with the given name. Inside the try block, call query("SELECT * FROM users"). The connection should automatically close when the block ends.

    Next, demonstrate multiple resources. Print a blank line, then === Multiple Resources ===. Use try-with-resources with both a Connection (using the same name) and a Session (using the username), declared in that order with semicolons. Inside the try block, first call query("INSERT INTO logs") on the connection, then call performAction with the input action on the session. Watch how resources close in reverse order!

You will receive three inputs in order: connection name (String), username (String), and action (String).

Notice how try-with-resources eliminates the need for explicit close calls and finally blocks. The resources are guaranteed to close even if exceptions occur, and multiple resources close in reverse declaration order!

Cheat sheet

The try-with-resources statement automatically closes resources when the block completes. Any class implementing AutoCloseable can be used:

try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
    String line = reader.readLine();
}  // Automatically closed here

Multiple resources can be managed by separating them with semicolons. They close in reverse order of declaration:

try (FileReader fr = new FileReader("input.txt");
     BufferedReader br = new BufferedReader(fr)) {
    // Use both resources
}  // br closed first, then fr

To create a custom auto-closeable class, implement the AutoCloseable interface and its close() method:

public class DatabaseConnection implements AutoCloseable {
    public DatabaseConnection() {
        System.out.println("Connection opened");
    }
    
    @Override
    public void close() {
        System.out.println("Connection closed");
    }
}

Try it yourself

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String connectionName = scanner.nextLine();
        String username = scanner.nextLine();
        String action = scanner.nextLine();
        
        // === Single Resource ===
        // TODO: Print the header
        // TODO: Use try-with-resources to create a Connection
        // TODO: Inside the try block, call query("SELECT * FROM users")
        
        // === Multiple Resources ===
        // TODO: Print a blank line and the header
        // TODO: Use try-with-resources with both Connection and Session
        // TODO: Inside the try block:
        //       - Call query("INSERT INTO logs") on the connection
        //       - Call performAction with the input action on the session
        
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming