Prefer try-with-resources to try-finally
- 2판 제목 : 없음
- 3판 제목 : try-finally 보다는 try-with-resources를 사용하라
자바에는 InputStream
, OutputStream
, java.sql.Connection
등 사용 후 직접 닫아주어 자원을 반환하는 객체들이 있다.
자원의 반환은 누락하기가 쉬운 관계로 종료자를 활용할 수 있지만 여러가지 단점이 있기에 쉽게 사용하기 어려운 문제가 있다.
전통적으로는 아래와 같이 try-finllay
를 이용해 무조건 호출되는 finally
블록에서 자원을 반환하였다.
1 | static String firstLineOfFile(String path) throws IOException { |
허나 반환해야하는 자원이 둘 이상이면 코드가 배우 난잡해진다.
1 | static void copy(String src, String dst) throws IOException { |
자바 7부터는 try-with-resources
를 활용해 이 복잡한 구조를 해소할 수 있게 되었다.
try-with-resources
를 사용하려면, 이를 이용하는 자원이 AutoCloseable
인터페이스를 구현해야하는데,
이미 상당수의 자원들이 해당 인터페이스를 구현하고 있다.
1 | public interface AutoCloseable { |
실제로 적용한다면 아래와 같은 코드를 얻게 된다.
1 | static void copy(String src, String dst) throws IOException { |
좀 더 가독성이 향상되었음을 느낄 수 있다.
장점은 가독성뿐만이 아니다.
아래와 같은 예제를 보자.
1 | static String firstLineOfFile(String path) throws IOException { |
위의 예제에서 readline
과 내부적으로 호출될 close
함수 양쪽에서 에외가 발생한다면 어떻게 될까?
만약 둘 다 예외가 발생한다면, close
에서 발생한 예외는 숨겨지고 readLine
에서 발생하 예외만 출력된다.
즉 개발자가 직접 손을 대야하는 영역에 한해서만 예외를 출력해주는 것이다.
물론 숨겨진 예외들도 StackTrace 내에 suppressed
표식을 달고 출력은 된다.
또한 보통의 try-finally
처럼 catch
블록을 추가하는 것도 가능하다.
위의 예제를 살짝 수정해보자.
1 | static String firstLineOfFile(String path, String defaultValue) throws IOException { |