[Java] try-with-resources

SeongHo Hong
4 min readJul 10, 2022

상황

요즘 코드숨 코스를 참여하고 있는데요. 이번에도 리뷰 받은 주제를 중심으로 더 깊게 학습해보겠습니다. 과제에서 이런 코드가 있었습니다. 이 코드의 문제점은 무엇일까요?

write(), flush() 단계에서 예외가 발생하면 close() 를 호출해주지 못하는 문제가 있습니다. 이 문제를 개선하기 위해서 try-catch-finally 문을 사용하고자 했습니다.

finally는 반드시 실행되니까 scope가 종료될 때 close()를 반드시 실행해주게 됩니다.

원리파악

IDE 에서는 진작에 try with resources 를 추천해주셨지…

여기까지 작성했는데 IntelliJ 에서 try 부분에 자꾸 노란불이 들어와있는 겁니다. 저걸 실행해보니 아래와 같이 코드가 변경되었습니다.

아니 close를 빠트리는 방식으로 코드를 수정하다니?? 뭔가 이상하다 싶어서 다시 기존 코드로 되돌려 뒀습니다 🤣

리뷰를 받고 찾아보니 이게 try-with-resources 문 이었습니다. 방금전 코드에서는 finally 처럼 try-catch 문의 최종 시점에 close가 호출되게 됩니다.

앞서 나왔듯 리소스를 다룰 때 적절히 close 해주지 못하는 위험성이 있는데 Java 언어에서 이걸 좀 더 간편하게 다룰 수 있게 해줍니다. Java 7 부터 이 기능을 사용할 수 있습니다. 이 구문을 사용할 수 있는 조건은 클래스가 AutoCloseable 이라는 인터페이스를 구현하고 있어야 합니다.

java 안에서 다양한 곳에서 사용되고 있구요.

리소스를 다루는 곳에서 엄청나게 많이 활용되고 있습니다

Spring 에서도 AutoCloseable을 적극적으로 사용하는 것을 볼 수 있습니다.

그런데 리소스가 여러개 일때도 있겠죠? 그럴 때는 try 다음의 괄호 안에 세미콜론으로 구분해서 여러개의 리소스를 선언할 수 있습니다. 아래는 책의 예제를 참고했습니다.

in, out 순서로 할당했는데 close를 호출하는건 역순으로 호출됩니다. out, int 순서로 close가 호출됩니다.

AutoCloseable vs Closeable

좀 더 들여다보면 AutoCloseable도 있고 Closeable도 있습니다.

AutoCloseable

  • try-with-resources statement 를 위해 도입됨
  • JDK 7
  • void close() throws Exception

Closeable

  • backward compatiblity를 유지하기 위해 남아있음
  • JDK 5
  • void close() throws IOException

사실 거의 똑같은데, 다른 점이 있다면 Closeable은 예외를 IOException으로 범위가 좀 더 좁습니다. 그리고 Closeable은 AutoCloseable 보다 더 오래된 인터페이스라서 하위 호환성 유지를 위해 그대로 남아있습니다.

정리

  • IDE가 추천하면 한번 더 들여다보자
  • 사용후 close를 호출해줘야한다면 try-with-resources 를 적극 사용하자
  • AutoCloseable 은 인터페이스라서 필요한 곳에서 구현해서 사용하면 된다

참고

--

--

SeongHo Hong

Software Engineer 🧑‍💻https://github.com/cozzin