[Java] try with resource 사용에 관하여.
데이터 리소스를 활용하는 어플리케이션을 구현하던 중 리뷰어 분께 try with resource를 활용해보면 좋을 것 같다는 피드백을 받았다.
원래 데이터 리소스를 사용하는 과정에서 try catch finally 구조를 사용하고 있었다. 심지어 finally에서 리소스 해제조차 하지 않고 사용하고 있었다.
공부를 하다 보니 리소스를 해제하지 않으면 여러 예기치 못한 상황일때 리소스가 위험해질 수도 있겠다는 생각이 들었고, 이를 공부했다. 그런데 final에서 해제를 하면 해결 되는 문제이지 않은가? 라는 생각이 들었다.
그래서 try with resource 에 관해서 파헤쳐보기로 하였다.
그럼 try with resource를 사용하는 이유에 관하여 알아보자.
공부하며 내가 생각하여본 try with resouce에 관한 가장 큰 장점은 개발자가 신경쓰지 않아도 안전하게 자원을 반납할 수 있다는 것이다. 실수 혹은 에러로 인한 경우에도 안전하게 반납을 하게 된다.
.close()를 하는 과정에서 에러가 발생하더라도 자동으로 반납이 되게끔 설계 되어있다.
기존 try catch finally 에서는 final에서 직접 .close()하는 코드를 작성 했다면 , try with resouce 에서는 작성할 필요가 없다.
또 try catch finally 을 리소스를 사용할 때 사용하게 된다면,문제가 크게 두가지 있다.
첫번째로는, 자원을 활용하는 과정에서 오류가 생기게 된다면 ,try 부분에서 생긴 오류에 관해서는 예외가 보이지 않는다.
try 에러에 관한 스택 트레이스가 finally 에서 생긴 오류로 덮혀지게 되어버리는 것이다.
이 경우가 된다면 오류를 찾아가기 힘들어진다.
두번째로는 , finally에서 .close()를 하는 과정에서 오류가 날 경우에 finally 안에 있는 또 다른 객체의 .close()는 작동하지 않게 되어버린다.
앞에 있는 오류에 관한 처리 부분이 구현되어 있지 않기 때문인데, 이를 처리하기 위해서는 finally 안에 있는 각 .close()마다 예외처리를 또 해주어야하는 것이다. 이 작업이 번거로워지게 되는 것이다.
만약 try with resource를 사용하게 된다면 이 두가지 상황을 해결 할 수 있게 된다.
앞서 말한 첫번째의 경우가 생긴다면 두 예외 상황 모두를 스택 트레이스에서 확인 할 수 있다. try 의 예외를 우선적으로 판단하여 try 의 예외가 먼저 출력된 후에 Suppressed: 의 형태로 .close()의 예외 메시지도 출력되게 된다.
두번째의 상황에서는 try with resource가 자동으로 클래스 파일로 컴파일 시점에서 try catch finally 구문으로 변환을 통해 알어서 처리해주게 된다.
(오류가 생기더라도 tryPractice,tryPractice2 모두 close 된 것을 확인할 수 있다.)
즉 이 두가지 상황을 피할 수 있다는 점이다.