brunch
매거진 Effective Java

Effective Java3/E - 객체의 생성과 파괴

#09 try-finally보다는 try-with-resouces를 사용

by 이승현

Effective Java 3/E - 객체의 생성과 소멸


#09 try-finally 보다는 try-with-resource를 사용하라


Java 라이브러리에는 close 메서드를 호출해서 직접 닫아야 하는 InputStream, OutputStream 등이 있습니다.


try-finally 가 아닌, try-with-resource를 이용해서 닫는 방법에 대해 알아보겠습니다.




# try-finally


보통 finalizer를 통해 close 메서드를 호출하고 있지만, 이전에 언급했듯이 주의할 점들이 있습니다.

static String firstLineOfFile(String path) throws IOException {

BufferedReader br = new BufferedReader(new FileReader(path));

try {
return br.readLine();
} finally {
br.close(); // 최선이 아님
}
}


만약 close 메서드를 하나 더 호출해야 하는 상황이라면, 지저분합니다.

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-resource


Java 7에서 나온 try-with-resource를 이용하면 이러한 문제들을 해결할 수 있습니다.

이를 위해 AutoCloseable 인터페이스만 구현하면 됩니다.

AutoCloseable 인터페이스는 하나의 close 메서드만 정의되어 있습니다.
void close() throws Exception;


OutputStream을 보면, 아래와 같이 AutoCloseable 인터페이스가 이미 구현되어 있습니다.

스크린샷 2019-01-04 오전 10.52.14.png #01 OutputSteam class


이 외에도 많은 라이브러리들이 AutoCloseable 인터페이스를 구현하고 있습니다.

자세한 내용은 아래 링크를 참고해 주시기 바랍니다.

https://docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html


직접 구현해보면, 아래와 같이 구현할 수 있습니다.

static String firstLineOfFile(String path) throws IOException {

try(BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
// no finally and BufferedReader#close method.
}
static void copy(String src, String dst) throws IOException {

try(InputStream in = new FileInputStream(src)) {
try(OutputStream out = new FileOutputStream(dst)) {
byte[] buf = new byte[BUFFER_SIZE];
int n;
while ((n = in.read(buf)) >= 0) {
out.write(buf, 0, n);
}
}
// no finally and OutputStream#close method.
}
// no finally and InputStream#close method.
}


try-finally와 달리 try() 문 안에 AutoCloseable 인스턴스를 정의해야 합니다.

// try-finally
try {} finally {}
// try-with-resources
try(AutoCloseable instance) {}
매거진의 이전글Effective Java3/E - 객체의 생성과 파괴