본문 바로가기

독후감/Effective Java

9. try-finally 보다는 try-with-resources를 사용하라

자바 라이브러리에는 close메서드를 활용해 직접 닫아줘야 하는 자원이 많다.
이런 경우 자바에서는 전통적으로 try-finally가 사용되었다.

하지만 try-finally는 닫아줘야하는 자원이 2개만 되어도 굉장히 난잡해진다.

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();
        }
    } finally {
        in.close();
    }
}

자바 7에서는 try-with-resources 덕에 모두 해결되었다.
이 구조를 사용하려면 해당 자원이 AutoCloseable 인터페이스를 구현해야 한다.(단순히 void를 반환하는 close메서드만 있는 인터페이스이다.)
현재 각종 자바 라이브러리에서는 해당 클래스를 이미 확장(implements)해두었다.
아래는 상기 예제를 try-with-resources를 활용하여 작성한 것이다.

static void copy(String src, String dst) throws IOException {
    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);
    }
}

위 예제가 짧고 읽기 수월할 뿐 아니라 문제를 진단하기도 훨씬 좋다.
당연하게도 catch문도 사용할 수 있다.

static void copy(String path, String defaultVal) throws IOException {
    try (BufferedReader br = new BufferedReader(
        new FileReader(path)
    )) {
        return br.readLine();
    } catch (IOException e) {
        return defaultVal;
    }
}