Learning/TIL / / 2025. 3. 3. 20:30

[EFFECTIVE JAVA] 의식의 흐름대로 써보는 자바 close()와 try-with-resources 이야기

자바 close()? 그거 좀 귀찮네...

 

자바 하다 보면 꼭 마주치는 close(). InputStream, OutputStream, BufferedReader... 얘네 왜 이렇게 닫을 게 많은 걸까? 안 닫으면 뭐... 좀 곤란해진다.

 

왜 닫아야 하는지, 대충 요약하자면

 

  • 자원 낭비:
    • OS가 관리하는 애들이라 안 닫으면 언젠가 시스템이 맛이 갈 수도 있다.
  • 데이터 유실:
    • 버퍼에 있는 데이터는 사라질 수도 있고.
  • 안전 문제:
    • 예외 터져도 마무리는 해야 하지 않겠나?

 

그래서 뭐, 닫아야 한다고. 근데 왜 이렇게 말이 많은 거지?

 

개발자들이 자꾸 까먹고 안 닫는다. 그래서 문제가 생기는 거고.

 

옛날 방식, try-finally

 

예전엔 이걸로 해결했다.

static String firstLineOfFile(String path) throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        br.close();
    }
}
static void copy(String src, String dst) throws IOExeption () {
    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 {
        int.close();
    }
}



첫 번째는 그나마 괜찮은데, 여러 개 닫아야 하면 코드가 좀... 그렇다. 그리고 예외가 겹치면 디버깅이 좀 귀찮아진다.
finally 에서의 예외가 try 예외를 삼킬 수도 있다고 한다.

 

 

요즘 방식, try-with-resources

 

자바 7부터 나온 건데, 이걸 쓰면 좀 편해진다.

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);
    }
}


보다시피 코드가 훨씬 깔끔해진다. 예외가 여러 개 터져도 알아서 처리해 준다.

static String firstLineOfFile(String path, String defaultVal) {
    try (BufferedReader br = new BufferedReader(new FileReader(path))) {
        return br.readLine();
    } catch (IOExeptuin e) {
        return defaultVal;
    }
}

여기서 readLine과 보이지 않는 close 호출 양쪽에서 예외가 발생하면, close예외가 숨겨지고 readLine에서 발생한 예외가 기록된다고 한다.

 

결론

  • 자원 관리는 필수. try-with-resources 쓰면 편하다. 꼭 쓰자.
  • 예외 처리는 언제나 중요. 귀찮아도 하자.

 


 

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유