Skip to content

item 9 dodo4513

황도영 edited this page Mar 28, 2020 · 1 revision

아이템9 try-finally보다는 try-with-resources를 사용하라

  • 자바 라이브러리에는 close 메서드를 호출해 직접 닫아줘야 하는 자원이 많다. InputStream, OutputStream, java.sql.Connection 등이 좋은 예다. 자원 닫기는 클라이언트가 놓치기 쉬워서 예측할 수 없는 성능 문제로 이어지기도 한다.

try-fincally의 문제점

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-catch 지옥이 열린다.

  • try-finally 는 자원이 2개 이상인 경우 자원 회수를 위해 2중으로 try-catch 를 감싸야 한다.
  • 안쪽의 finally에서 예외가 발생한 경우 최초의 예외는 무시되어 디버깅이 힘들어진다.

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

2개 이상의 자원도 깔끔하게 처리 가능하다.

  • 자바 7이 투척한 try-with-resources 덕에 모두 해결되었다. 이 구조를 사용하려면 해당 자원이 AutoCloseable 인터페이스를 구현해야 한다. 단순히 void를 반환하는 close 메서드 하나만 덩그러니 정의한 인터페이스다. 자바 라이브러리와 서드파티 라이브러리들의 수많은 클래스와 인터페이스가 이미 AutoCloseable을 구현하거나 확장해뒀다.

핵심정리

꼭 회수해야 하는 자원을 다룰 때는 try-finall 말고, try-with-resources를 사용하자.
예외는 없다.
코드는 더 짧고 분명해지고, 만들어지는 예외 정보도 훨씬 유용하다.
try-finally로 작성하면 실용적이지 못할 만큼 코드가 지저분해지는 경우라도, try-with-resources로는 정확하고 쉽게 자원을 회수할 수 있다.

Clone this wiki locally