try-with-resources 자원 자동 회수

try-with-resources 를 사용하자

Posted on 2019-03-30

try-with-resources 자원 자동 회수


자바 라이브러리에는 close 메서드를 호출해 직접 회수해야 하는 자원이 많다.
이 문제를 해결하기 위해 Java7 부터 try-with-resources 구조를 지원한다. 이 구조를 사용하려면 해당 자원이 AutoCloseable 인터페이스를 구현해야 한다.

  • try 블록에 자원 객체를 선언하면 finally 블록에서 직접 close 메서드를 호출하지 않아도 try 블록이 끝나면 자동으로 자원을 회수해준다.
  • try 블록에서 사용하는 자원이 여러개라면 ;으로 구분하여 선언할 수 있다. 자원 회수는 선언한 역순으로 이루어진다.
  • 선언하는 자원이 많을수록 코드가 훨씬 간결해진다.
  • catch, finally 블록도 기존처럼 사용 가능하다.
// before
static void copy(String src, Strin 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();
    }
}

// after
static void copy(String src, Strin 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);
    }
}
// 자원을 회수해야하는 클래스를 작성한다면 AutoCloseable을 구현하자
public class MyResource implements AutoCloseable {
    @Override
    public void close() throws Exception {
        System.out.println("Closed MyResource");
    }
}

회수해야 하는 자원을 다룰 때는 try-finally 말고, try-with-resources를 사용하자.
코드는 더 짧고 분명해지고, 만들어지는 예외 정보도 훨씬 유용하다.

+ multiple-catch

catch 블록에서 잡은 예외들을 개별적으로 처리해야했다.
Java7 부터 하나의 catch 블록에 | 구분자를 두어 여러 예외를 묶어서 처리할 수 있다. 덕분에 불필요한 중복 코드를 제거할 수 있게 되었다.

// before
try {
    throwABCmethod();
} catch (AException ex) {
    someAorB(ex);
} catch (BException ex) {
    someAorB(ex);
} catch (CException ex) {
    someC(ex);
}

// after
try {
    throwABCmethod();
} catch (AException | BException ex) {
    someAorB(ex);
} catch (CException ex) {
    someC(ex);
}