brunch

You can make anything
by writing

C.S.Lewis

by 이승현 Jan 07. 2019

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

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

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 인터페이스가 이미 구현되어 있습니다.

#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 - 객체의 생성과 파괴
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari