[Java] 16. 예외 처리(Exception handling)(5) - 예외 되던지기, 연결된 예외

2024. 7. 9. 05:39·Java/Core
목차
  1. 예외 되던지기(exception re-throwing)
  2. 연결된 예외(chained exception)
  3. 왜 원인 예외로 등록해서 다시 예외를 발생시키나요?
  4. Example 8.23

예외 처리(5) - 예외 되던지기, 연결된 예외

예외 되던지기(exception re-throwing)

  • 앞서 말했던 것처럼 한 메서드에서 발생할 수 있는 예외가 여럿인 경우 몇 개는 try-catch문을 통해서 자체적으로 처리하고, 나머지는 선언부에 지정하여 호출한 메서드에서 처리하도록 함으로써 양쪽에서 나눠서 처리되도록 할 수 있다.

  • 심지어 단 하나의 예외에 대해서도 예외가 발생한 메서드와 호출한 메서드 양쪽에서 처리하도록 할 수 있다.

    • 이것은 예외를 처리한 후에 인위적으로 다시 발생시키는 방법을 통해서 가능한데, 이것을 예외 되던지기라고 한다.
  • 먼저 예외가 발생할 가능성이 있는 메서드에서 try-catch문을 사용해서 예외를 처리해주고 catch문에서 필요한 작업을 행한 후에 throw문을 사용해서 예외를 다시 발생 시킨다

    • 이 예외는 이 메서드를 호출한 메서드에게 전달되고 호출한 메서드의 try-catch문에서 예외를 또 다시 처리한다.
  • 이 방법은 예외가 발생한 메서드와 이를 호출한 메서드 양쪽 모두에서 처리해줘야 할 작업이 있을 때 사용된다

    • 주의) 예외가 발생할 메서드에서는 try-catch문을 사용해서 예외처리를 해줘야하는 동시에 메서드의 선언부에 발생할 예외를 throws에 지정해줘야 한다는 것이다.
class ExceptionEx17 {
    public static void main(String[] args) {
        try {
            method1();
        } catch (Exception e) {
            System.out.println("main메서드에서 예외가 처리되었습니다.");
        }
    }    // main메서드의 끝

    static void method1() throws Exception { // re-throwing하는 경우 throws를 지정해줘야 한다
        try {
            throw new Exception();
        } catch (Exception e) {
            System.out.println("method1메서드에서 예외가 처리되었습니다.");
            throw e;    // 다시 예외를 발생시킨다.
        }
    }    // method1메서드의 끝
}

  • 반환값이 있는 return문의 경우 catch블럭에도 return문이 있어야 한다.

    • 예외가 발생해도 값을 반환해야 하기 때문이다.

    • catch블럭에서 예외 되던지기를 해서 호출한 메서드로 예외를 전달하면 catch블럭에 return문이 없어도 된다

static int method1() {
        try {
                // ~~
                return 0;
        } catch (Exception e) {
                e.printStackTrace();
                // return 1; // catch블럭 내에서도 원래는 return문이 필요하다
                throw new Exception(); // return문 대신 예외를 호출한 메서드로 전달한다.
        } finally {
                // ~~
        }
}

연결된 예외(chained exception)

  • 한 예외가 다른 예외를 발생시킬 수도 있다.

  • 예외 A가 예외 B를 발생시켰다면, A를 B의 원인 예외(cause exception)이라고 한다.

try {
        startInstall(); // SpaceException 발생
        copyFiles();
} catch (SpaceException e) {
        InstallException ie = new InstallException("설치 중 예외 발생"); // 예외 생성
        ie.initCause(e); // InstallException의 원인 예외를 SpaceException으로 지정
        throw iel // InstallException을 발생시킨다
} catch (MemoryException me) {
        ...
}
  • initCause()로 원인 예외를 등록한다

  • initCause()는 Exception 클래스의 조상인 Throwable클래스에 정의되어 있기 때문에 모든 예외에서 사용가능하다

왜 원인 예외로 등록해서 다시 예외를 발생시키나요?

  • 원인1) 여러가지 예외를 하나의 큰 분류의 예외로 묶어서 다루기 위해서이다.

    • 하나로 묶어서 다루기 위해 만약 catch의 참조변수에 부모 클래스 참조변수를 넣으면, 실제로 발생한 예외가 어떤 것인지 알 수 없는 문제가 발생한다.

    • 그래서 예외가 원인 예외를 포함시킬 수 있게 한 것이다.

  • 원인2) checked 예외를 unchecked예외로 바꿀 수 있도록 하기 위함이다.

    • 예외를 RuntimeException으로 감싸버리면 unchecked 예외가 된다.

    • throw new RuntimeException(new MemoryException("메모리 부족"));

      • initCause()대신 RuntimeException의 생성자를 사용할 수 있다.
    • 이렇게 하면 더 이상 메서드의 선언부에 memoryException을 선언하지 않아도 된다.

Example 8.23

class ChainedExceptionEx {
    public static void main(String args[]) {
        try {
            install();
        } catch(InstallException e) {
            e.printStackTrace();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }    // main메서드의 끝

    static void install() throws InstallException {
        try {
            startInstall();        // 프로그램 설치에 필요한 준비를 한다.
            copyFiles();        // 파일들을 복사한다.
        } catch(SpaceException se) {
            InstallException ie = new InstallException("설치 중 예외 발생");
            ie.initCause(se);
            throw ie;
        } catch(MemoryException me) {
            InstallException ie = new InstallException("설치 중 예외 발생");
            ie.initCause(me);
            throw ie;
        } finally {
            deleteTempFiles();    // 프로그램 설치에 사용된 임시파일들을 삭제한다.
        }    // try의 끝
    }    // install메서드의 끝

    static void startInstall() throws SpaceException, MemoryException {
        if(!enoughSpace()) {    // 충분한 공간이 없으면
            throw new SpaceException("설치할 공간이 부족합니다.");
        }

        if(!enoughMemory()) {    // 충분한 메모리가 없으면
            throw new MemoryException("메모리가 부족합니다.");
//            throw new RuntimeException(new MemoryException("메모리가 부족합니다."));
        }
    }    // startInstall메서드의 끝

    static void copyFiles()            { /* 파일들을 복사하는 코드를 적는다. */ }
    static void deleteTempFiles()    { /* 임시파일들을 삭제하는 코드를 적는다.*/ }

    static boolean enoughSpace() {
        // 설치하는데 필요한 공간이 있는지 확인하는 코드를 적는다.
        return false;
    }

    static boolean enoughMemory() {
        // 설치하는데 필요한 메모리공간이 있는지 확인하는 코드를 적는다.
        return true;
    }
}    // ExceptionTest클래스의 끝

class InstallException extends Exception {
    InstallException(String msg) {
        super(msg);
    }
}

class SpaceException extends Exception {
    SpaceException(String msg) {
        super(msg);
    }
}

class MemoryException extends Exception {
    MemoryException(String msg) {
        super(msg);
    }
}

참조) Java의 정석 3rd edition(남궁성, 도우출판)

'Java > Core' 카테고리의 다른 글

[Java] 18. 불변 객체  (0) 2024.10.15
[Java] 17. Object 클래스  (0) 2024.10.15
[Java] 15. 예외 처리(Exception handling)(4) - finally블럭, 자동 자원 반환: try-with-resources문, 사용자 정의 예외  (0) 2024.07.09
[Java] 14. 예외 처리(Exception handling)(3) - 메서드에 예외 선언하기  (0) 2024.07.09
[Java] 13. 예외 처리(Exception handling)(2) - try-catch 문  (0) 2024.07.09
  1. 예외 되던지기(exception re-throwing)
  2. 연결된 예외(chained exception)
  3. 왜 원인 예외로 등록해서 다시 예외를 발생시키나요?
  4. Example 8.23
'Java/Core' 카테고리의 다른 글
  • [Java] 18. 불변 객체
  • [Java] 17. Object 클래스
  • [Java] 15. 예외 처리(Exception handling)(4) - finally블럭, 자동 자원 반환: try-with-resources문, 사용자 정의 예외
  • [Java] 14. 예외 처리(Exception handling)(3) - 메서드에 예외 선언하기
lumana
lumana
배움을 나누는 공간 https://github.com/bebeis
  • lumana
    Brute force Study
    lumana
  • 전체
    오늘
    어제
    • 분류 전체보기 (452) N
      • Software Development (27) N
        • Performance (0)
        • TroubleShooting (1)
        • Refactoring (0)
        • Test (8) N
        • Code Style, Convetion (0)
        • DDD (0)
        • Software Engineering (18)
      • Java (71) N
        • Basic (5)
        • Core (21)
        • Collection (7)
        • 멀티스레드&동시성 (13)
        • IO, Network (8)
        • Reflection, Annotation (3)
        • Modern Java(8~) (12) N
        • JVM (2) N
      • Spring (53) N
        • Framework (12)
        • MVC (23)
        • Transaction (3) N
        • AOP (11) N
        • Boot (0)
        • AI (0)
      • DB Access (1)
        • Jdbc (1)
        • JdbcTemplate (0)
        • JPA (14)
        • Spring Data JPA (0)
        • QueryDSL (0)
      • Computer Science (125)
        • Data Structure (27)
        • OS (14)
        • Database (10)
        • Network (21)
        • 컴퓨터구조 (1)
        • 시스템 프로그래밍 (23)
        • Algorithm (29)
      • HTTP (8)
      • Infra (1) N
        • Docker (1) N
      • 프로그래밍언어론 (15)
      • Programming Language(Sub) (77) N
        • Kotlin (1) N
        • Python (25)
        • C++ (51)
        • JavaScript (0)
      • FE (11)
        • HTML (1)
        • CSS (9)
        • React (0)
        • Application (1)
      • Unix_Linux (0)
        • Common (0)
      • PS (13)
        • BOJ (7)
        • Tip (3)
        • 프로그래머스 (0)
        • CodeForce (0)
      • Book Review (4)
        • Clean Code (4)
      • Math (3)
        • Linear Algebra (3)
      • AI (7)
        • DL (0)
        • ML (0)
        • DA (0)
        • Concepts (7)
      • 프리코스 (4)
      • Project Review (6)
      • LegacyPosts (11)
      • 모니터 (0)
      • Diary (0)
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
lumana
[Java] 16. 예외 처리(Exception handling)(5) - 예외 되던지기, 연결된 예외
상단으로

티스토리툴바

단축키

내 블로그

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

블로그 게시글

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

모든 영역

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

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