[Effective Java] Item 9. try-finally 보다는 try-with-resources 를 사용하라
전통적으로 자원이 제대로 닫힘을 보장하는 수단으로 try-finally가 쓰였지만 몇 개의 단점이 있다.
단점 1. try와 finally 블록 모두에서 예외가 발생했을 때
예외는 try 블록과 finally 블록 모두에서 발생할 수 있다. 만약 기기에 물리적 문제가 생겨 firstLineOfFile 메서드 try 블록의 readLine 메서드와 finally 블록의 close 메서드가 실패했다면 두 번째 예외가 첫 번째 예외를 집어삼켜버린다.
그렇다면 첫 번째 예외에 관한 정보는 남지 않게 되어 디버깅이 상당히 어려워진다.
단점 2. 자원이 여러 개일 때
만약 자원이 하나가 아니라 자원이 둘 이상이라면 try-finally 방식의 코드는 매우 지저분해진다.
이러한 단점 때문에 우리는 try-with-resources를 사용해야 한다.
자바의 try-with-resources는 자바 7부터 도입된 기능으로, 자동으로 자원을 닫아줘서 예외처리와 관련된 코드를 더 간결하게 작성할 수 있게 해 준다.
try-with-resources를 사용하려면 try문을 작성하고 괄호 안에 자원을 선언한다. 자원은 try문을 벗어나면 자동으로 닫히므로, finally 블록에서 자원을 닫는 코드를 작성할 필요가 없다.
AutoCloseable 인터페이스는 close() 메서드를 정의하고 있으며, 이 메서드는 자원을 닫는 역할을 하기 때문에 try-with-resources는 AutoCloseable 인터페이스를 구현한 클래스의 인스턴스만 자원으로 사용할 수 있다.
아래 코드들은 위의 try-finally 방식을 try-with-resources 방식으로 재구성한 코드이다.
readLine과 코드에는 나타나 있지 않는 close 호출 양쪽 모두에서 예외가 발생한다면, close에서 발생한 예외는 숨겨지고 readLine에서 발생한 예외가 기록된다. 이처럼 프로그래머에게 보여줄 예외 하나만 보존되고 여러 개의 다른 예외를 숨길 수 있다.
두 개의 자원이 있음에도 불구하고 try-finally에 비해 매우 짧고 우아하다.
try-with-resources에서도 catch 절을 사용할 수 있다. catch 절 덕분에 try 문을 더 중첩하지 않고도 다수의 예외를 처리할 수 있다. 위 코드는 firstLineOfFile 메서드를 수정하여 파일을 열거나 데이터를 읽지 못했을 때 예외를 던지는 대신 기본값을 반환하도록 한 것이다.