자바 라이브러리에는 close 메서드를 호출해 직접 회수해야 하는 자원이 많다.
이 문제를 해결하기 위해 Java7 부터 try-with-resources
구조를 지원한다. 이 구조를 사용하려면 해당 자원이 AutoCloseable
인터페이스를 구현해야 한다.
;
으로 구분하여 선언할 수 있다. 자원 회수는 선언한 역순으로 이루어진다.// 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를 사용하자.
코드는 더 짧고 분명해지고, 만들어지는 예외 정보도 훨씬 유용하다.
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);
}