상세 컨텐츠

본문 제목

[매일메일] try-with-resources에 대해 설명해 주세요

본문

이것도 솔직히 첨 들어 본다.

커넥션, 입출력 스트림과 같은 자원을 사용한 후에는 자원을 해제해서 성능, 메모리 누수 등을 방지해야한다.

try-with-resources는 이러한 자원을 자동으로 해제하는 기능, java 7부터 도입

try (BufferedReader br = new BufferedReader(new FileReader("path"))) {
    return br.readLine();
} catch (IOException e) {
    return null;
}

AutoCloseable 인터페이스를 구현한 객체를 사용해야 하고, try() 괄호 내에서 변수를 선언해야 함

 

그렇다면 try-catch-finally 대신 try-with-resources를 사용해야 하는 이유는?

BufferedReader br = null;
try {
    br = new BufferedReader(new FileReader("path"));
    return br.readLine();
} catch (IOException e) {
    return null;
} finally {
    if (br != null) {
        try {
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

try-catch-finally는 finally 블록에서 close()를 명시적으로 호출해야 함.

하지만 close() 호출을 누락하거나 이 과정에서 또 다른 예외가 발생 시, 예외 처리가 복잡해지는 문제가 있음

 

또한 여러 개의 자원을 다룰 경우, 먼저 close()를 호출한 자원에서 에러가 발생하면 다음에 close()를 호출한 자원은 해제되지 않음

이를 해결하려면 추가적인 try-catch-finally가 필요하므로 가독성이 떨어지고, 실수 가능성이 높음

 

try-with-resources를 사용하면 try-catch-finally의 문제를 해결할 수 있다.

  • try 블록이 종료될 때 close()를 자동으로 호출해서 자원을 해제
  • finally 블록 없이도 자원을 안전하게 정리, 코드가 간결
  • try 문에서 여러 자원을 선언, 선언된 반대 순서로 자동 해제

Suppressed Exception(억제된 예외)

: 예외가 발생했지만 무시되는 예외를 의미

try-with-resources는 close() 과정에서 발생한 예외를 Suppressed Exception으로 관리

-> 추가 예외도 함께 추적 가능하고, 자원을 안전하게 해제하면서 예외를 효율적으로 처리 가능

 

try-catch-finally는 close()를 호출 시, 예외가 발생하면 원래 예외가 사라지고 close() 에서 발생한 예외만 남을 수 있음

디버깅이 어렵기 때문에 Throwable의 addSuppressed()를 사용하면 문제를 해결할 수 있지만, 코드가 복잡해질 수 있음.

 

그렇다면 파이썬에선? 

파이썬의 경우에도 with라는 방식을 제공한다.

try-except-finally로 try-catch-finally의 python 버전으로 사용 가능하다.

try:
    with open("some/path", "r") as file:
    	print(file.readline())
except IOError:
    print("error")

이런 식으로 with를 사용할 경우 finally 구문을 사용하지 않고 자원을 해제하는 것이 가능하다.

관련글 더보기