Try with Resources

Introduction

Try-with-resources (Java 7+) automatically closes resources. No need for finally block.


Basic Syntax

try (ResourceType resource = new ResourceType()) {
    // Use resource
}
// Resource automatically closed

Before Java 7 (Old Way)

import java.io.*;

public class Main {
    public static void main(String[] args) {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader("test.txt"));
            String line = br.readLine();
            System.out.println(line);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // Manual cleanup
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Java 7+ (New Way)

import java.io.*;

public class Main {
    public static void main(String[] args) {
        // Resource auto-closed
        try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
            String line = br.readLine();
            System.out.println(line);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // br.close() called automatically
    }
}

Simple Example

import java.io.*;

public class Main {
    public static void main(String[] args) {
        try (FileReader fr = new FileReader("test.txt")) {
            int data = fr.read();
            while (data != -1) {
                System.out.print((char) data);
                data = fr.read();
            }
        } catch (IOException e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}

Multiple Resources

import java.io.*;

public class Main {
    public static void main(String[] args) {
        // Multiple resources separated by semicolon
        try (FileReader fr = new FileReader("input.txt");
             BufferedReader br = new BufferedReader(fr)) {

            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            System.out.println("Error: " + e.getMessage());
        }
        // Both closed automatically (reverse order)
    }
}

AutoCloseable Interface

Only resources implementing AutoCloseable can be used.

import java.io.*;

class MyResource implements AutoCloseable {
    MyResource() {
        System.out.println("Resource opened");
    }

    void doSomething() {
        System.out.println("Using resource");
    }

    @Override
    public void close() {
        System.out.println("Resource closed");
    }
}

public class Main {
    public static void main(String[] args) {
        try (MyResource resource = new MyResource()) {
            resource.doSomething();
        }
        // close() called automatically
    }
}

Output:

Resource opened
Using resource
Resource closed

File Copy Example

import java.io.*;

public class FileCopy {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("source.txt");
             FileOutputStream fos = new FileOutputStream("destination.txt")) {

            int data;
            while ((data = fis.read()) != -1) {
                fos.write(data);
            }
            System.out.println("File copied successfully");

        } catch (IOException e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}

With Catch and Finally

import java.io.*;

public class Main {
    public static void main(String[] args) {
        try (FileReader fr = new FileReader("test.txt")) {
            // Use resource
            int data = fr.read();
        } catch (FileNotFoundException e) {
            System.out.println("File not found");
        } catch (IOException e) {
            System.out.println("IO error");
        } finally {
            System.out.println("Finally block");
        }
        // Order: close resource → catch → finally
    }
}

Custom AutoCloseable

class DatabaseConnection implements AutoCloseable {
    private String connectionId;

    DatabaseConnection(String id) {
        this.connectionId = id;
        System.out.println("Connection opened: " + id);
    }

    void executeQuery(String query) {
        System.out.println("Executing: " + query);
    }

    @Override
    public void close() {
        System.out.println("Connection closed: " + connectionId);
    }
}

public class Main {
    public static void main(String[] args) {
        try (DatabaseConnection conn = new DatabaseConnection("DB001")) {
            conn.executeQuery("SELECT * FROM users");
        }
        // Connection automatically closed
    }
}

Java 9+ Enhancement

Can use effectively final variables.

import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        // Java 9+: Create resource outside
        FileReader fr = new FileReader("test.txt");
        BufferedReader br = new BufferedReader(fr);

        // Use in try-with-resources
        try (fr; br) {  // Just reference variables
            String line = br.readLine();
            System.out.println(line);
        }
    }
}

Closing Order

Resources closed in reverse order of creation.

class Resource implements AutoCloseable {
    private String name;

    Resource(String name) {
        this.name = name;
        System.out.println(name + " opened");
    }

    @Override
    public void close() {
        System.out.println(name + " closed");
    }
}

public class Main {
    public static void main(String[] args) {
        try (Resource r1 = new Resource("R1");
             Resource r2 = new Resource("R2");
             Resource r3 = new Resource("R3")) {
            System.out.println("Using resources");
        }
    }
}

Output:

R1 opened
R2 opened
R3 opened
Using resources
R3 closed
R2 closed
R1 closed

Exception in close()

class ResourceWithError implements AutoCloseable {
    @Override
    public void close() {
        throw new RuntimeException("Error closing resource");
    }
}

public class Main {
    public static void main(String[] args) {
        try (ResourceWithError r = new ResourceWithError()) {
            System.out.println("Using resource");
        } catch (Exception e) {
            System.out.println("Caught: " + e.getMessage());
        }
    }
}

Suppressed Exceptions

If both try and close() throw, close() exception is suppressed.

class Resource implements AutoCloseable {
    @Override
    public void close() {
        throw new RuntimeException("Close exception");
    }
}

public class Main {
    public static void main(String[] args) {
        try (Resource r = new Resource()) {
            throw new RuntimeException("Try exception");
        } catch (Exception e) {
            System.out.println("Main exception: " + e.getMessage());

            // Get suppressed exceptions
            for (Throwable suppressed : e.getSuppressed()) {
                System.out.println("Suppressed: " + suppressed.getMessage());
            }
        }
    }
}

Output:

Main exception: Try exception
Suppressed: Close exception

Benefits

  1. Automatic cleanup - no manual close()
  2. Cleaner code - less boilerplate
  3. No resource leaks - guaranteed cleanup
  4. Exception handling - suppressed exceptions
  5. Multiple resources - easy management

When to Use

Use try-with-resources for:

  • File operations (FileReader, FileWriter)
  • Database connections (Connection, Statement)
  • Network sockets (Socket, ServerSocket)
  • Streams (InputStream, OutputStream)
  • Scanner, BufferedReader
  • Any AutoCloseable resource

Quick Reference

// Single resource
try (Resource r = new Resource()) {
    r.use();
}

// Multiple resources
try (Resource r1 = new Resource1();
     Resource r2 = new Resource2()) {
    r1.use();
    r2.use();
}

// With catch
try (Resource r = new Resource()) {
    r.use();
} catch (Exception e) {
    // handle
}

// With catch and finally
try (Resource r = new Resource()) {
    r.use();
} catch (Exception e) {
    // handle
} finally {
    // additional cleanup
}

// Custom AutoCloseable
class MyResource implements AutoCloseable {
    public void close() {
        // cleanup code
    }
}

Common Mistakes

// ✗ Wrong - not AutoCloseable
class MyClass { }  // Doesn't implement AutoCloseable

try (MyClass obj = new MyClass()) {  // Compile error!
    // ...
}

// ✗ Wrong - trying to use after try
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
    String line = br.readLine();
}
br.readLine();  // Error: br out of scope

// ✓ Correct - implements AutoCloseable
class MyResource implements AutoCloseable {
    public void close() { }
}

try (MyResource r = new MyResource()) {
    // use r
}
// r closed automatically

Exam Tips

Remember:

  1. Java 7+ feature
  2. AutoCloseable interface required
  3. Automatic resource closing
  4. Multiple resources with semicolon
  5. Closed in reverse order
  6. Can have catch and finally
  7. Suppressed exceptions available
  8. Java 9+ allows pre-created variables
  9. No manual close() needed
  10. Cleaner than finally block

Common Questions:

  • What is try-with-resources?
  • When introduced?
  • Which interface required?
  • Multiple resources syntax?
  • Closing order?
  • Benefits?
  • With catch/finally?
  • Suppressed exceptions?
  • Java 9 enhancement?
  • Common use cases?