[Java] try-with-resources
상황
요즘 코드숨 코스를 참여하고 있는데요. 이번에도 리뷰 받은 주제를 중심으로 더 깊게 학습해보겠습니다. 과제에서 이런 코드가 있었습니다. 이 코드의 문제점은 무엇일까요?
write(), flush() 단계에서 예외가 발생하면 close() 를 호출해주지 못하는 문제가 있습니다. 이 문제를 개선하기 위해서 try-catch-finally 문을 사용하고자 했습니다.
finally는 반드시 실행되니까 scope가 종료될 때 close()를 반드시 실행해주게 됩니다.
원리파악
여기까지 작성했는데 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 은 인터페이스라서 필요한 곳에서 구현해서 사용하면 된다