Java의 try-with-resources의 주요 목적은 리소스의 자동적이고 올바른 해제를 보장하는 것입니다. 이 구문이 Java 7에 도입되기 전에는 프로그래머가 finally 블록에서 리소스를 수동으로 닫아야 했습니다. 이는 코드의 중복과 빈번한 오류 발생으로 이어졌습니다.
Java 6 이전에는 리소스(열린 파일, 스트림, 연결)를 finally를 통해 수동으로 관리해야 했기 때문에 종종 리소스 누수가 발생했습니다.
수동으로 작성된 리소스 종료 코드로 인해 버그가 발생하기 쉬우며, 특히 여러 예외와 복잡한 catch 블록 계층을 다룰 때 더욱 그렇습니다. 오류 발생 시 close() 호출이 보장되지 않습니다.
Java 7부터는 try-with-resources 구문이 도입되어, AutoCloseable 인터페이스를 구현하는 각 리소스에 대해 close() 메소드를 자동으로 호출하도록 보장합니다.
코드 예제:
try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) { String line = reader.readLine(); System.out.println(line); } catch (IOException e) { e.printStackTrace(); } // reader는 자동으로 닫힙니다.
주요 특징:
질문 1: 리소스가 try-with-resources를 위해 구현해야 할 인터페이스는 무엇인가요?
AutoCloseable. 이 인터페이스(또는 Closeable)를 구현하는 모든 객체는 해당 구조에서 사용할 수 있습니다.
질문 2: 여러 개의 리소스가 try-with-resources에 있을 경우, 어떤 순서로 리소스가 닫히나요?
리소스는 선언된 반대 순서로 닫힙니다 (스택-LIFO):
try (A a = new A(); B b = new B()) { ... } // b.close()가 먼저 호출되고, 그 다음 a.close()가 호출됩니다.
질문 3: AutoCloseable 구현이 없는 비표준 객체(예: 네트워크 연결)에 try-with-resources를 사용할 수 있나요?
아니요, 그러나 자신의 클래스에서 AutoCloseable을 수동으로 구현할 수 있습니다. 이렇게 하면 객체가 try-with-resources와 호환됩니다.
개발자들은 JDBC Connection과 Statement를 finally를 통해 수동으로 닫았습니다. 두 번째 예외가 발생하면 Statement가 닫히지 않았고, 연결이 "중단"되고 오류를 숨겼습니다.
장점:
단점:
파일 로드 모듈에 try-with-resources를 도입한 후 모든 스트림이 자동으로 닫히고 코드가 훨씬 짧아졌으며 파일 설명자의 누수 버그가 사라졌습니다.
장점:
단점: