|

자바 try-with-resources는 왜 필요할까: close를 깜빡하는 실수를 줄이는 방법

자바 try-with-resources는 왜 필요할까: close를 깜빡하는 실수를 줄이는 방법
try-with-resources는 예외 처리 코드에서 자원을 닫는 책임을 문법 안으로 가져옵니다.

try-with-resources는 Java에서 파일, 스트림, DB 연결처럼 닫아야 하는 자원을 다룰 때 쓰는 문법입니다. 단순히 코드가 짧아지는 기능이 아니라, 예외가 발생해도 close를 놓치지 않게 만드는 구조입니다.

핵심은 자원 생성과 정리 책임을 try 문장 안에 함께 적는 것입니다. 이 글은 Oracle Java Tutorial과 AutoCloseable 문서를 기준으로 finally close와 어떤 차이가 있는지 정리합니다.

자바 try-with-resources 핵심 요약 카드
AutoCloseable을 구현한 객체는 try 블록이 끝날 때 자동으로 close됩니다.

try-with-resources가 필요한 이유

파일을 열거나 네트워크 연결을 만들면 작업이 끝난 뒤 닫아야 합니다. 문제는 정상 흐름에서는 close를 잘 적어도, 중간에 예외가 발생하면 정리 코드가 건너뛰기 쉽다는 점입니다.

BufferedReader reader = new BufferedReader(new FileReader("input.txt"));
String line = reader.readLine();
reader.close();

위 코드는 단순해 보이지만 `readLine()`에서 예외가 발생하면 `close()`까지 도달하지 못할 수 있습니다. 그래서 전통적으로 finally 블록에서 close를 처리했습니다.

finally close는 안전하지만 코드가 길어진다

BufferedReader reader = null;
try {
    reader = new BufferedReader(new FileReader("input.txt"));
    System.out.println(reader.readLine());
} finally {
    if (reader != null) {
        reader.close();
    }
}

이 방식은 정리 책임을 드러내지만, 자원이 여러 개가 되면 코드가 빠르게 복잡해집니다. close 중에도 예외가 날 수 있어 예외 흐름을 읽기도 어려워집니다.

try-with-resources 기본 구조

try 괄호 안에서 resource를 선언하면 try 블록이 끝날 때 자동으로 close가 호출됩니다. 정상 종료든 예외 발생이든 정리 흐름이 문법에 포함됩니다.

try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"))) {
    System.out.println(reader.readLine());
}

닫아야 하는 객체를 try 괄호 안에 선언한다는 기준만 기억하면 됩니다. 블록을 벗어나면 Java가 close 호출을 처리합니다.

AutoCloseable이 기준이다

try-with-resources에 들어가는 객체는 `AutoCloseable`을 구현해야 합니다. `Closeable`도 AutoCloseable의 하위 인터페이스라 파일 스트림, reader, writer 같은 많은 IO 객체가 여기에 해당합니다.

class MyResource implements AutoCloseable {
    @Override
    public void close() {
        System.out.println("정리");
    }
}

try (MyResource resource = new MyResource()) {
    System.out.println("사용");
}

직접 만든 클래스도 close가 필요한 자원이라면 AutoCloseable을 구현해 같은 문법으로 다룰 수 있습니다.

여러 resource를 선언할 때

try 괄호 안에는 여러 resource를 선언할 수 있습니다. 선언한 순서의 반대로 close가 호출됩니다. 나중에 만든 자원을 먼저 닫는 구조입니다.

try (
    BufferedReader reader = new BufferedReader(new FileReader("input.txt"));
    BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))
) {
    writer.write(reader.readLine());
}

언제 특히 써야 할까

  • 파일, 스트림, reader, writer를 사용할 때
  • JDBC Connection, PreparedStatement, ResultSet처럼 닫아야 하는 DB 객체를 다룰 때
  • 테스트에서 임시 자원을 만들고 정리해야 할 때
  • 직접 만든 resource 객체에 정리 로직이 있을 때

실무 체크리스트

  1. 객체가 AutoCloseable 또는 Closeable인지 확인한다
  2. 자원 생성 코드를 try 괄호 안으로 옮긴다
  3. try 블록 안에는 실제 사용 로직만 남긴다
  4. 여러 resource는 의존 관계를 생각해 선언 순서를 정한다
  5. close에서 발생할 수 있는 예외도 로그나 처리 정책을 확인한다

정리

자바 try-with-resources는 close 코드를 없애는 문법이 아니라, 자원 정리 책임을 try 문장에 묶어 실수를 줄이는 문법입니다. 닫아야 하는 객체가 있다면 먼저 AutoCloseable 여부를 확인하는 습관이 좋습니다.

Java 문법 흐름은 자바 제네릭 와일드카드 extends super 차이, 자바 stream과 for문 차이, 자바 Optional은 언제 써야 할까와 함께 보면 좋습니다. 외부 기준은 Oracle Java Tutorial – The try-with-resources Statement, Java API – AutoCloseable, Java API – Closeable를 확인했습니다.

함께보면 좋은 글