JAVA/Effective Java

[아이템 9] try-finally보다는 try-with-resources를 사용하라

꾸준함. 2024. 1. 24. 07:29

Java 7부터 try-with-resources 구문이 등장해 try-finally는 더 이상 최선의 방법이 아닙니다.
try-with-resources를 사용할 경우 장점은 아래와 같습니다.

  • 코드가 훨씬 간결해져 가독성이 좋아짐
  • 예외가 두 개 이상 발생했을 때 예외를 잡아먹지 않기 때문에 전부 확인 가능

 

코드가 훨씬 간결해져 가독성이 좋아짐

자원이 하나인 경우 try-finally 절도 괜찮아 보이지만 자원이 두 개 이상이 되어 try-finally 절이 중첩이 되는 순간부터 가독성이 급격하게 안 좋아집니다.

 
단일 자원

 

 

 
다중 자원

 

 
다중 자원 코드를 보고 혹여나 아래와 같이 코드를 작성하면 단일 try-finally 절로 작성이 되지 않을까?라고 생각할 수 있겠지만 이렇게 작성할 경우 finally 절 내 out.close()에서 예외가 발생할 경우 in.close()가 실행도 되지 않을 수 있는 문제점이 있습니다.
 

 
 
적어도 반납할 자원에 대한 close() 메서드가 정상적으로 호출됐다는 것을 보장하기 위해서는 중첩 구조로 코드로 작성할 수밖에 없습니다.
비슷한 예시로 저자가 본인이 작성한 Java Puzzler 책을 언급했는데 코드는 아래와 같습니다.
 

 
 
해당 코드 또한 out.close()에서 IOException이 아닌 RuntimeException 발생 시 in.close()가 대처를 못하여 in.close()가 호출도 안된다는 문제를 야기하는 코드입니다.
이처럼 try-finally는 가독성뿐만 아니라 코드 안정성 측면에서 열위를 보입니다.
반면 try-with-resources 절 도입 시 중첩 구조를 피할 수 있고 가독성 좋은 코드를 작성할 수 있을 뿐더러 target 폴더 내 생성된 byte code를 보면 close() 메서드들이 반드시 호출되도록 내부적으로 코드가 작성된 것을 확인할 수 있습니다.

  • 반드시 호출이 된다는 것이지 반드시 실행 결과 성공을 보장하는 것은 아닙니다.

 

 

 

예외가 두 개 이상 발생했을 때 예외를 잡아먹지 않기 때문에 전부 확인 가능

try-with-resources 절의 또 다른 장점은 예외를 잡아먹지 않는다는 것입니다.
try-finally 절이 중첩되어 있을 경우 마지막 예외만 터미널에 찍히는 것을 확인할 수 있습니다.
 

마지막 예외만 출력

 
 
반면, try-with-resources를 적용 시 모든 예외가 찍히는 것을 확인할 수 있습니다.
사실 장애 원인 분석을 할 때 마지막 예외보다는 최초로 발생한 예외가 더 중요하기 때문에 try-with-resources를 권장합니다.
 

모든 예외 출력

 
 
try-with-resources가 모든 예외를 출력하는 이유는 target 폴더 내 바이트 코드를 확인하면 알 수 있습니다.
바이트 코드를 보면 예외가 발생할 때마다 잡아서 addSuppressed 메서드를 호출하는 것을 확인할 수 있고 해당 메서드 덕분에 마지막 예외가 다른 예외를 잡아먹지 않고 전부 출력할 수 있습니다.


 

정리

try-finally보다 try-with-resources가 가독성 측면 그리고 안전성 측면에서 모두 좋으므로 try-finally 절이 보인다면 모두 try-with-resources로 변경하는 것을 권장합니다.
 

참고

이펙티브 자바
이펙티브 자바 완벽 공략 1부 - 백기선 강사님
 

반응형