📗Java

[Java] Chained Exception

kkyu0718 2023. 7. 20. 18:55

Error 와 Exception 

에러 (Error) : 프로그램 코드에 의해서 수습될 수 없는 심각한 오류. 프로그램을 강제 종료시킬 수 있다.

예외 (Exception) : 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류. 예외는 처리를 하여 프로그램의 비정상 종료를 방지해야 하고 이를 예외처리라고 부릅니다. 

 

Runtime Exception 클래스

Throwable 클래스

예외는 두 가지로 분류됩니다.

RuntimeException 클래스

프로그래머의 실수로 발생하는 예외

예외 처리가 선택적이며 컴파일 때 체크되지 않고 런타임에 발생하는 예외 - Unchecked Exception

ex) NullPointerException, IndexOutOfBoundException 

이 외의 Exception 클래스 

사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외 - 예외처리 필수 Checked Exception

컴파일때 체크되며 예외 처리를 하지 않으면 컴파일이 되지 않는 예외 - Checked Exception

ex) IOException, SQLException

 

사용자 정의 예외

Exception 과 Error 클래스 모두 Throwable 를 상속받습니다. 따라서 사용자 정의 예외를 정의할거면 Throwable 클래스 상속을 받은 Runtime Exception 를 상속받아 정의합니다.

 

public class BusinessException extends RuntimeException {

    private ErrorCode errorCode;

    public BusinessException(String message, ErrorCode errorCode) {
        super(message);
        this.errorCode = errorCode;
    }

    public BusinessException(ErrorCode errorCode) {
        super(errorCode.getMessage());
        this.errorCode = errorCode;
    }

    public ErrorCode getErrorCode() {
        return errorCode;
    }

}

 

Chained Exception

연결된 예외 (Chained Exception) 를 쓰는 이유

  • 여러 예외를 큰 분류의 예외로 묶기 위함
  • 필수 예외를 선택 예외로 바꾸기 위함

1. 여러 예외를 큰 분류의 예외로 묶기

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

install() 메소드 자체에는 여러 예외를 선언해주고 메인 코드에서는 하나의 코드로 감출 수 있습니다. (캡슐화)

 

try {
   install();
} catch(InstallException e { // SpaceException과 MemoryException을 하나로 묶음
	e.printStackTrace();
} catch(Exception e) {
	e.printStackTrace();
}

실행 결과 - initCause 설정으로 원인 예외가 Caused By 로 드러난다

2. 필수 처리 예외(Checked)를 선택 처리(Unchecked)로 바꾸기

필수 처리 예외로 선언하면 코드에 try-catch 블록이 길어져 복잡해집니다. 

void startInstall() throws SpaceException, MemoryException {
    if(!enoughSpace())		// 충분한 설치 공간이 없는 경우
    	throw new SpaceException("설치할 공간이 부족합니다.");
    
    if(!enoughMemory())		// 충분한 메모리가 없는 경우
    	throw new MemoryException("메모리가 부족합니다.");
}

 

SpaceException, MemoryException 모두 Runtime Exception 이 아니기 때문에 Checked Exception 인 상황입니다. 두 개의 예외 처리를 해줘야 컴파일로 넘어갈 수 있습니다. (위 코드에서는 메소드 선언부에 처리해주었습니다.)

 

이를 Runtime Exception 으로 바꾼다면 필수 예외 처리를 선택으로 바꿀 수 있습니다.

void startInstall() throws SpaceException {
    if(!enoughSpace())		// 충분한 설치 공간이 없는 경우
    	throw new SpaceException("설치할 공간이 부족합니다.");
    
    if(!enoughMemory())		// 충분한 메모리가 없는 경우
    	throw new RuntimeException(new MemoryException("메모리가 부족합니다.")); // 원인 예외로 등록
}

Runtime Exception 안에 원인 예외로 Memory Exception 를 넣었습니다. 이렇게 하면 Runtime Exception 이라 메소드에 예외 선언을 안해줘도 되며 에러가 날때 원인 예외 (Memory Exception)를 확인할 수 있습니다.