Java Try-with-Resources 마스터: 자동 리소스 관리 완전 해설
Java Try-with-Resources 마스터하기
Java try-with-resources 문이 리소스 처리를 단순화하고 누수 방지, 코드 가독성 향상시키는 방법 탐구.
try‑with‑resources 구문은 괄호 안 선언된 모든 리소스가 블록 종료 시(정상 또는 급작스런) 자동 닫힘 보장. 리소스는 AutoCloseable 또는 Closeable 구현 객체.
문법:
try (ResourceType resource = new ResourceType(...)) { // 리소스 사용 } catch (ExceptionType e) { // 예외 처리 }
사용법:
try 절 내 리소스 인스턴스화. - 사용 또는 닫기 중 발생 가능 에러에 대한 예외 처리 선언.
참고: AutoCloseable 구현 객체만 자동 관리 가능.
예제 1: 파일 안전하게 읽기
import java.io.*; public class Main { public static void main(String[] args) { try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) { String line; while ((line = br.readLine()) != null) { System.out.println("Line =>" + line); } } catch (IOException e) { System.out.println("IOException in try‑with‑resources block =>" + e.getMessage()); } } }
test.txt 없을 때 출력:
IOException in try‑with‑resources block =>test.txt (No such file or directory)
파일 존재 시 출력:
Line =>test line
여기서 BufferedReader가 블록 후 자동 닫혀 finally 절 불필요.
억제된 예외 (Suppressed Exceptions)
try 블록과 리소스 닫기 모두 예외 던지면 try 블록 예외 우선, 다른 예외 억제. Throwable.getSuppressed()로 억제된 예외 검색 가능:
catch (IOException e) { System.out.println("Thrown exception =>" + e.getMessage()); for (Throwable t : e.getSuppressed()) { System.out.println("Suppressed exception =>" + t); } }
왜 Try-with-Resources인가?
1. 수동 정리 불필요
Java 7 전엔 리소스 닫기 위해 finally 블록 필수. 보일러플레이트 추가, 닫기 중 예외 시 finally 내 중첩 try‑catch 필요. Try-with-resources로 정리 암시적:
BufferedReader br = null; try { br = new BufferedReader(new FileReader("test.txt")); // br 사용 } catch (IOException e) { // 처리 } finally { if (br != null) { try { br.close(); } catch (IOException ignored) {} } }
위 패턴보다 아래가 더 간결하고 에러 덜 발생:
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) { // br 사용 }
2. 한 문장에 여러 리소스
세미콜론으로 여러 리소스 구분 선언. 선언 역순으로 닫힘.
try (Scanner scanner = new Scanner(new File("testRead.txt")); PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) { while (scanner.hasNext()) { writer.print(scanner.nextLine()); } }
3. Java 9 개선
Java 9에서 리소스 로컬 선언 필수 조건 완화. 기존 변수 재사용 가능:
Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) { // 코드 }
같은 리소스 다른 곳 필요 시 가독성 향상.
더 깊은 통찰은 공식 AutoCloseable 문서와 Java 9 JEP 326 릴리스 노트 참조.