Be an Overachiever
AutoCloseable interface 본문
AutoCloseable interface를 통해 코드를 깔끔하게 리팩토링 해보자.
JDBC를 사용할 경우 마지막에 connection 객체를 close() 처리를 해주어야한다.
이 경우 주로 finally 문에서 close() 처리를 한다.
1 2 3 4 5 6 7 8 9 10 | Connection connection = null; try { connection = pool.getConnection(); // do something } catch (ConnectionException e) { LOGGER.error("Connection Exception 발생"); } finally { connection.close(); } | cs |
하지만 만약 pool에서 connection 객체를 가져올 때 ConnectionException이 발생한다면 어떻게 될까?
connection 객체는 처음 선언한 것 처럼 null 이지만 finally 블록에서 null.close()를 실행하려고 하기때문에
NullPointerException이 발생할 수 있다.
.....
Socket 통신에서 Input Stream 을 예를 들어보면 close() 처리를 할 때 다음과 같이 이중으로 try-catch 문을 작성해야할 수도 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | InputStream input = null; try { input = socket.getInputStream(); // do something } catch (IOException e) { LOGGER.error("IO Exception 발생"); } finally { try { input.close(); } catch (IOException e2) { LOGGER.error("InputStream.close : IO Exception 발생"); } } | cs |
여기서 input이 null인 경우 NullPointerException이 발생할 수 있기 때문에 if문 처리도 필요할 것이다.
1 2 3 4 5 6 7 8 9 10 | // ...생략 } finally { if (input != null) { try { input.close(); } catch (IOException e2) { LOGGER.error("InputStream.close : IO Exception 발생"); } } } | cs |
만약 Connection 또는 IO Stream과 같이 사용 후 close() 처리를 해야하는 객체를 여러 메소드에서 사용해야 할 경우 리소스를 위해서 필요하지만 똑같은 코드가 반복이 된다. (DRY 하지 않다) 이를 깔끔하게 처리하기 위해서 JDK 1.7에서 AutoCloseable interface가 추가되었다.
close()가 필요한 API를 까보면 아마 Closeable, AutoCloseable을 찾을 수 있을 것이다.
테스트를 해보자.
AutoCloseable interface를 구현하여 다음과 같이 try () 안에 사용할 closeable 객체를 선언한다.
이를 try-with-resources statement라 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public class CloseableClass implements AutoCloseable { public CloseableClass(int num) throws Exception { if (num == 1) { throw new Exception(); } } @Override public void close() throws Exception { System.out.println("닫힘"); } public void hello() { System.out.println("Hello World"); } public static void main(String[] args) { try (CloseableClass closeableObj = new CloseableClass(2)) { closeableObj.hello(); } catch (Exception e) { System.out.println("에러발생"); } } } | cs |
위와 같이 try() 안에 선언한 CloseableClass의 객체는 try catch 블록 종료후 자동으로 close()를 호출하게 된다.
* Constructor에 인자를 넣어 객체를 가져올 때 Exception이 일어나는 것을 구현해 보았다.
궁금하면 객체를 생성할 때 파라미터로 1을 넣어서 결과를 확인해 보자.
Comments