자바 라이브러리에는 close 메서드를 직접 호출해서 닫아줘야 하는 자원이 많다. 전통적으로 자원이 제대로 닫힘을 보장하는 수단으로 try-finally가 쓰였다. 예외가 발생하거나 메서드에서 반환되는 경우를 포함해서 말이다.
static void copy(String src, String dst) throws IOException {
InputStream in = new FileInputStream(src);
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 {
in.close();
out.close();
}
}
자바 7부터 try-with-resources 가 생겼다. 이 구조를 사용하려면 해당 자원이 AutoCloseable 인터페이스를 구현해야 한다. 단순히 void를 반환하는 close 메서드 하나만 덩그러니 정의한 인터페이스이다.
public interface AutoCloseable {
void close() throws Exception;
}
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);
}
}
꼭 회수해야 하는 자원을 다룰 때는 try-finally 말고, try-with-resources를 사용하자. 예외는 없다. try-finally는 실용적이지 못할 만큼 코드가 지저분해지는 경우라도, try-with-resources로는 정확하고 쉽게 자원을 회수할 수 있다.
참고) 이펙티브 자바