자바 라이브러리에는 close
메서드를 호출해 직접 닫아줘야 하는 자원이 많다.
InputStream
, OutputStream
, java.sql.Connection
등이 좋은 예이다.
자원 닫기는 클라이언트가 놓치기 쉬워서 예측할 수 없는 성능 문제로 이어지기도 한다.
전통적으로 자원이 제대로 닫힘을 보장하는 수단으로 try-finally
가 쓰였다.
예외가 발생하거나 메서드에서 반환되는 경우를 포함해서 말이다.
try {
자원 열기
자원 활용
} finally {
자원 닫음
}
위와 같은 구조에서는 자원 활용과 닫기 양쪽에서 예외가 발생하면 자원 닫기의 예외가 자원 활용의 예외를 집어삼켜 버린다.
그러면 스택 추적 내역에 자원 활용 예외에 관한 정보는 남지 않게 되어, 디버깅을 어렵게 한다.
try-with-resources
는 try-finally
구조와는 조금 다르다.
try( 자원 열기 ... ) {
자원 활용
}
이 구조에서는 자원 활용가 자원 닫기 양쪽에서 예외가 발생하면 자원 닫기 예외는 숨겨지고 자원 활용 예외가 기록된다.
버려지거나 집어삼켜진 것이 아니라 숨겨진 것이기에 스택 추적 내역에 'suppressed'라는 꼬리표를 달고 출력된다고 한다.
이 구조를 사용하려면 해당 자원이 AutoCloseable
인터페이스를 구현해야 한다.
단순히 void를 반환하는 close
메서드 하나만 덩그러니 정의한 인터페이스다.
자바 라이브러리와 서드파티 라이브러리들의 수많은 클래스와 인터페이스가 이미 AutoClosable을 구현하거나 확장해뒀다.
try-with-resources
는 try-finally
와 달리 코드가 더 짧아지고 분명해지며, 만들어지는 예외 정보도 더 유용한다.
그렇기에 꼭 자원을 회수해야 하는 경우에는 try-with-resources
를 사용하자!
자바 공부 열심히 하시는 모습 보기 좋네요