[Effective Java] 아이템9 - try-with-resources를 사용하자

Note: 이 글은 Effective Java 책을 읽으면서 중요한 내용 및 알아야 하는 지식들을 정리한 글입니다.

전통적으로 자원이 제대로 닫힘을 보장하는 수단으로 try-finally가 쓰였다.

static void copy(String src, String dst) throws IOException {
    InputStream in = new FileInputStream(src);
    try {
        OutputStream out = new FileOutputStream(dst);
        try {
            byte[] buf = new byte[BUFFER_SIZE];
            int n;
            while ((n = in.read(buf)) >= 0)
                out.write(buf, 0, n);
        } finally {
            out.close(); // (1) 자원 닫기
        }
    } finally {
        in.close(); // (2) 자원 닫기
    }
}

자원을 1개 이상 사용한다면, 안쪽에서 한번 닫아주고 바깥쪽에서 한번 더 닫아줘야 한다. try-catch 문을 한번 더 개선한 로직이 자바 7부터 사용할 수 있는 try-with-resources이다.

try-with-resources -> AutoCloseable 인터페이스를 구현하고 사용하자

[아이템8]에서 한 번 짚고 넘어간 적 있는 AutoCloseable 인터페이스를 회수하려는 자원이 구현하면 된다.

닫아야 하는 자원을 뜻하는 클래스를 작성한다면 AutoCloseable를 반드시 구현하자.

자바7에서는 많은 클래스를 이 인터페이스를 구현하도록 만들어 놨는데, 아래에서 사용할 FileInputStreamFileOutputStreamAutoCloseable를 구현한 클래스다.

따라서 try 에서 예외가 발생하면 자동으로 close 된다.

static void copy(String src, String dst) throws IOException {
    // (1) try 문 안에 직접 닫아야하는 자원들을 생성한다.
    try (InputStream   in = new FileInputStream(src);
         OutputStream out = new FileOutputStream(dst)) {
        byte[] buf = new byte[BUFFER_SIZE];
        int n;
        while ((n = in.read(buf)) >= 0)
            out.write(buf, 0, n);
    }
}

짧고 읽기 수월할 뿐 아니라 문제를 진단하기도 훨씬 쉽다.

참고 : 숨겨진 예외도 그냥 버려지지 않고, 스택 추적 내역에 suppressed 꼬리표를 달고 출력된다. 자바7에서 Throwable에 추가된 getSuppressed메서드를 사용하면 프로그램 코드에서 가져올 수도 있다.

이렇게 try-with-resources를 사용하면 try문을 중첩하지 않고도 다수의 예외를 처리할 수 있다.

댓글남기기