try-with-resources & kotlin의 대체 방식
try-catch-finally
전통적인 자바의 try-catch-finally 패턴
java
FileInputStream fis = null;
try {
fis = new FileInputStream("test.txt");
// ... 파일 읽기 작업
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}- close() 호출 누락 위험(자원 누수)
- finally 블록이 장황하고 가독성이 떨어짐
- close()에서도 예외를 던져 추가적인 예외 처리가 필요해 코드 복잡도 증가
try-with-resources
java 7 부터 추가된 문법. 기존에는 try-finally 블록에서 직접 close를 호출해야 했는데, 이를 간소화하고 예외 처리 안정성을 높여줌.
java
try (FileInputStream fis = new FileInputStream("test.txt")) {
// ... 파일 읽기
} catch (IOException e) {
e.printStackTrace();
}- AutoCloseable 인터페이스 구현 객체만 사용 가능
- JDBC Connection, PreparedStatement, ResultSet, FileInputStream, BufferedReader 등
- 여러 자원도 한 번에 처리 가능
- 실행 중 예외 + 자원 해제 중 예외를 모두 안전하게 관리
Suppressed Exception (억제된 예외)
Suppressed Exception은 예외가 발생했지만 무시되는 예외를 의미한다.
원래 예외(Primary Exception)를 유지하면서 추가 예외도 함께 추적할 수 있고, 자원을 안전하게 해제하면서 예외를 효율적으로 처리할 수 있다.
java
Throwable[] suppressed = e.getSuppressed(); // 억제된 예외 조회 가능kotliin의 자원 관리 - use {}
Kotlin에는 try-with-resources 문법이 없다.
대신 Kotlin 표준 라이브러리의 확장 함수 use()를 활용한다.
AutoCloseable 또는 Closeable 을 구현한 객체에 적용 가능하다.
kotlin
FileInputStream("test.txt").use { fis ->
// ... 파일 처리
}- 블록이 종료되면 자동으로 close() 호출
- null-safe한 자원 관리
- I/O, JDBC 등 명시적인 자원 관리가 필요한 작업에서 매우 유용
동작방식
use() 내부에서 다음 흐름을 자동으로 처리한다.
kotlin
try {
// block 실행
} catch (e: Throwable) {
// block 내부 오류
} finally {
resource.close() // 자동 close
}즉, try-with-resources와 동일한 안정성을 보장함
스프링 + Jpa 환경에서는?
- EntityManager, Connection을 직접 다루지 않는다면
- 스프링이 트랜잭션 종료 시 자원 자동 정리
- use {}를 직접 사용할 일이 거의 없음
- (단, File, Stream, Socket 같은 I/O 작업을 할 때는 여전히 필요)