JAVA/리팩터링

[이펙티브 자바 - 아이템9] try-finally 보다는 try-with-resources를 사용하라

dev_rosieposie 2023. 5. 20. 17:57

 자원 반납  

자바 라이브러리에는 close메소드를 호출하여 직접 닫아줘야 하는 자원이 있다

ex) 대표적으로 InputStream, OutputStream, java.sql.Connection

 

자원반납을 해야하는 이유

접근할 때, File Descriptor를 생성해서 소모하는데 자원을 반납하지 않는경우 File Descriptor가 재활용이 되지않아

File Descriptor leak이 발생될 수 있으며 이는 어플리케이션의 문제로 이어질 수 있음

 

참고

멘토님 &

https://docs.oracle.com/cd/E23095_01/Platform.93/ATGInstallGuide/html/s0607detectingfiledescriptorleaks01.html

 

 

 

try-finally 방식의 코드 

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, finally에서 발생할 수 있는데 디버깅이 어려워짐

 

try-with-resources 방식의 코드 

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);
    }
}
  • 해당 자원이 AutoClosable 인터페이스를 구현함으로써 자동으로 자원이 회수됨
  • 코드가 간결해지고 문제 진단하기도 편리
  • catch절 사용가능

 

 구현 및 확장 

public class FileInputStream extends InputStream {

public abstract class InputStream implements Closeable {

public interface Closeable extends AutoCloseable {
    void close() throws IOException;
}

 

 정리  

  • 회수하는 자원을 다룰 때는 try-finally 보다 try-with-resources 사용
  • 정확하고 쉽게 자원을 회수 할 수 있기 때문