본문 바로가기

Reading/Effective Java

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

자바 라이브러리에는 close() 메소드를 호출해 직접 닫아줘야 하는 자원이 많다.

InputStream, OutputStream, java.sql.Connection 등이 예시다.

자원 닫기는 클라이언트가 놓치기 쉬워 성능 문제로 이어지기도 하는데, finalizer는 믿을 수 없으니 try-finally가 쓰였다.

 

try-finally


try-finally는 두가지 단점을 가진다.

 

1. 마지막에 나온 예외가 앞의 예외들을 집어삼킨다.

만약 물리적 이슈로 readLine 메소드가 예외를 던지고, 같은 이유로 close() 메소드도 실패를 하며 예외를 던진다면

close()에서 발생한 예외가 br.readLine()에 대한 예외를 집어 삼킨다.

즉, 첫번째 예외에 관한 정보가 남지 않아 실제 시스템에서 디버깅을 몹시 어렵게한다.

 

static String firstLineOfFile(String path) throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        br.close();
    }
}

 

2. 코드의 가독성이 떨어진다.

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

 

try-with-resources


try-finally의 단점들을 모두 잡았다.

자바7에 추가된 Try-with-Resource를 사용하면 코드 가독성도 좋고 try를 중첩하지 않아 다수의 예외처리도 가능하다.

숨겨진 예외들도 스택 추적 내역에 suppressed 꼬리표를 달고 출력된다.

위 firstLineOfFile에서 발생하던 예외 두개는, close()에서 발생한 예외는 숨겨지고 readRine에서 발생한 예외가 기록된다.

 

또한 Throwable에 추가된 getSuppressed() 메소드를 이용하면 프로그램 코드에서 가져올 수도 있다. 

단 해당 자원이 AutoCloseable 인터페이스를 구현해야한다.(https://ktaes.tistory.com/10)

아래는 try 중첩이 사라지고 훨씬 가독성도 올라간 위의 copy() 메소드다.

 

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);
    }
}

 

 

* 위 글은 EffectiveJava 3/E 책 내용을 정리한 글로, 저작권 관련 문제가 있다면 댓글로 남겨주시면 즉각 삭제조치 하겠습니다.