[Effective-Java] Chapter2 #9. try-finally보다는 try-with-resources를 사용하라

2023. 3. 9. 11:44·Reference/Effective-Java

자바 라이브러리에는 close 메서드를 호출해 직접 닫아주어야 하는 비메모리 자원들이 많다.

예를 들어, InputStream, OutputStream, java.sql.Connection 등이 좋은 예시다.

문제는 이 자원 닫기를 클라이언트 측에서 수행해주면 다행이지만, 놓치면 예측 불가능한 성능 문제로 이어진다.

전통적으로 자원이 제대로 닫힘을 보장하는 수단으로 try-finally가 사용되었다.

 

📌 try-finally
public static String firstLineOfFile(String path) throw IOException {
    BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        br.close();
    }
}

문제는 다음과 같이 자원이 둘 이상일 때, 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 블록 모두에서 발생할 수 있다.

readLine 메서드와, 자원을 해제하는 close 메서드 호출 동시에 예외가 발생하면, 두 번째 예외가 첫 번째 예외를 집어삼킨다.

그러면 스택 추적 내역에 첫 번째 예외 정보는 남지 않고, 디버깅을 굉장히 어렵게 만든다.

물론 두 번째 예외 대신 첫 번째 예외를 기록하도록 코드를 수정하는 것이 불가능하지 않지만 가독성이 바닥까지 떨어진다.

 

📌 try-with-resources

이 구조를 사용하려면 해당 자원이 AutoCloseable 인터페이스를 구현할 필요는 있지만, AutoCloseable은 단순히 void를 반환하는 close 메서드 하나만 덩그러니 있다.

닫아야 하는 자원을 뜻하는 클래스를 작성한다면, 반드시 구현하자.

 

// 자원을 회수하는 최선책
public static String firstLineOfFile(String path) throw IOException {
    try (BufferedReader br = new BufferedReader(new FileReader(path))) {
        return br.readLine();
    } catch (Exception e) {
        return defaultVal;
    }
}

try-finally에서는 두 개 이상의 자원을 쓸 때, 중첩 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);
	}
}

코드를 이렇게 작성하면 close가 알아서 호출해주며, 예외가 발생해도 close에서 발생한 예외는 숨겨지고 첫 번째 예외가 기록된다.

혹여 숨겨진 예외들은 스택 추적 내역에 suppressed 꼬리표를 달고 출력된다.

코드는 더 짧고 분명해지고, 만들어지는 예외 정보도 훨씬 유용한 try-with-resources를 사용해 자원을 회수하자.

저작자표시 비영리 (새창열림)
'Reference/Effective-Java' 카테고리의 다른 글
  • [Effective-Java] Chapter3 #11. equals를 재정의하려거든 hashCode도 재정의하라
  • [Effective-Java] Chapter3 #10. equals는 일반 규약을 지켜 재정의하라
  • [Effective-Java] Chapter2 #8. finalizer와 cleaner 사용을 피하라
  • [Effective-Java] Chapter2 #7. 다 쓴 객체 참조를 해제하라
나죽못고나강뿐
나죽못고나강뿐
싱클레어, 대부분의 사람들이 가는 길은 쉽고, 우리가 가는 길은 어려워요. 우리 함께 이 길을 가봅시다.
  • 나죽못고나강뿐
    코드를 찢다
    나죽못고나강뿐
  • 전체
    오늘
    어제
    • 분류 전체보기 (454)
      • Computer Science (60)
        • Git & Github (4)
        • Network (17)
        • Computer Structure & OS (13)
        • Software Engineering (5)
        • Database (9)
        • Security (5)
        • Concept (7)
      • Frontend (21)
        • React (13)
        • Android (4)
        • iOS (4)
      • Backend (77)
        • Spring Boot & JPA (50)
        • Django REST Framework (14)
        • MySQL (8)
        • Nginx (1)
        • FastAPI (4)
      • DevOps (24)
        • Docker & Kubernetes (11)
        • Naver Cloud Platform (1)
        • AWS (2)
        • Linux (6)
        • Jenkins (0)
        • GoCD (3)
      • Coding Test (112)
        • Solution (104)
        • Algorithm (7)
        • Data structure (0)
      • Reference (134)
        • Effective-Java (90)
        • Pragmatic Programmer (0)
        • CleanCode (11)
        • Clean Architecture (2)
        • Test-Driven Development (4)
        • Relational Data Modeling No.. (0)
        • Microservice Architecture (2)
        • 알고리즘 문제 해결 전략 (9)
        • Modern Java in Action (0)
        • Spring in Action (0)
        • DDD start (0)
        • Design Pattern (6)
        • 대규모 시스템 설계 (6)
        • JVM 밑바닥까지 파헤치기 (4)
      • Service Planning (2)
      • Side Project (5)
      • AI (0)
      • MATLAB & Math Concept & Pro.. (1)
      • Review (15)
      • Interview (1)
      • IT News (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃
  • 공지사항

    • 취업 전 계획 재조정
    • 취업 전까지 공부 계획
    • 앞으로의 일정에 대하여..
    • 22년 동계 방학 기간 포스팅 일정
    • 중간고사 기간 이후 포스팅 계획 (10.27~)
  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
나죽못고나강뿐
[Effective-Java] Chapter2 #9. try-finally보다는 try-with-resources를 사용하라

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.