자바 라이브러리에 존재하는 close 메서드를 필요로 하는 자원들이 있다. (예: InputStream, java.sql.Connection 등)
전통적으로 try-finally가 많이 쓰였다.
try-finally
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
import java.io.*;
// 자원을 하나 사용할 때 publicclassFinallyExample { static String firstLineOfFile(String path)throws IOException { BufferedReaderbr=newBufferedReader(newFileReader(path)); // 기기의 물리적인 문제가 생긴다면 try { return br.readLine(); // 첫번째 예외 발생 } finally { br.close(); // 두번째 예외 발생 } // 결론적으로 첫번째 예외에 대한 추적 내역이 사라지게 된다. } }
// 자원을 두 개 사용할 때 publicclassFinallyExample { static String copy(String src, String dst)throws IOException { InputStreamin=newFileInputStream(src); try { OutputStreamout=newFileOutputStream(dst); try { byte[] buf = newbyte[BUFFER_SIZE]; int n; while ((n = in.read(buf)) >= 0) out.write(buf, 0, n); } finally { out.close(); } } finally { in.close(); } } }
자원이 늘어날수록 코드가 너무 지저분해진다.
try-with-resources 방식
자바 7부터 추가됨
사용하려면 해당 자원이 AutoCloseable 인터페이스를 구현해야 함 (닫아야 하는 자원을 뜻하는 클래스를 작성할 때)
1 2 3 4 5 6 7 8 9 10
import java.io.*;
// 자원을 하나 사용할 때 publicclassWithResourcesExample { static String firstLineOfFile(String path)throws IOException { try (BufferedReaderbr=newBufferedReader(newFileReader(path))) { return br.readLine(); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
import java.io.*;
// 자원을 두 개 사용할 때 publicclassWithResourcesExample { staticvoidcopy(String src, String dst)throws IOException { // 복수의 자원을 처리함 try (InputStreamin=newFileInputStream(src); OutputStreamout=newFileOutputStream(dst)) { byte[] buf = newbyte[BUFFER_SIZE]; int n; while ((n = in.read(buf)) >= 0) out.write(buf, 0, n); } } }
코드가 더 짧아지고 자원 선언에서 발생한 예외가 그 이후의 예외로 인해 사라지지 않는다.
catch 절도 동일하게 사용 가능하다.
핵심 정리
꼭 회수해야 하는 자원을 다룰 때에는 try-finally 말고, try-with-resources를 사용하자.