본문 바로가기
Java

[EffectiveJava] Item 9 try-finally 보다는 try-with-resources를 사용하라

by 신입같은 3년차 2020. 12. 12.

Java 라이브러리에는 close 메서드를 호출하여 직접 닫아줘야 하는 자원들이 많다.

대표적인 예로는 InputStream, OutputStream, java.sql.Connection이 좋은 예이다.

자원을 닫는 방식은 클라이언트가 놓치기 쉬워, 예측할 수 없는 성능 문제로 이어지기도 한다.

이러한 문제에대한 안전망으로 finalizer를 활용하고 있지만 Item8에서 공부한 내용처럼 언제 어떻게 동작할지 모르기 때문에 믿을만하지 못하다.

그래서 전통적으로 많이 사용되어온 방식은 try-finally가 많이 사용되었다.

다음 예제는 실제로 취업 준비시절에 JSP에서 사용하였던 제 코드입니다

public static void close(Connection con, Statement stmt) {
    try {
        if (stmt != null) {
            stmt.close();
            stmt = null;
        }

        if (con != null) {
            con.close();
            con = null;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

안전한 방식이지만 close가 늘어날때마다 복잡해지고 close메서드를 제대로 구현하지 못하고 놓칠 가능성도 충분하다.

또한 try와 finally안에서 예외가 발생할 확률이 있는데 이러한 경우 finally에서 또 try-finally를 사용하여 보기조차 힘들고 실제로 디버깅 하기도 힘들것입니다.

이러한 문제를 해결하기위해서 Java7에서는 try-with-resources를 제공합니다.

이러한 문제를 해결하기 위해서는 해당 자원이 AutoCloseable 인터페이스를 구현해야 합니다.

AutoCloseable는 void를 반환하는 단순 close()메서드만 존재합니다

public interface AutoCloseable {
    void close() throws Exception;
}

꼭 회수해야 하는 자원을 다룰 때는 try-finally 보다 try-with-resources를 사용하도록 하자.

코드는 더 짧아지고 만들어지는 예외 정보도 훨씬 유용하다.

다음은 AutoCloseable를 직접 implements하여 직접 구현한 테스트 코드입니다.

try-with-resources를 사용하였으며 내부 메서드를 실행한뒤 close를 실행한 결과를 확인할 수 있습니다.

class AutoCloseableExample implements AutoCloseable{
    @Override
    public void close() throws Exception {
        System.out.println("AutoCloseable close() 호출");
    }


    public void print() {
        System.out.println("print 실행 !!");
    }
}

public class AutoCloseableApplication {
    public static void main(String[] args) throws Exception{

        try(AutoCloseableExample a = new AutoCloseableExample()) {
            a.print();
        }
    }
}

//실행 결과 
print 실행 !!
AutoCloseable close() 호출
반응형

댓글