[Java] Why - 사용자 정의 예외가 필요한 이유.

하쮸·2025년 9월 29일

Error, Why, What, How

목록 보기
38/64

1. 자바 예외 클래스 계층 구조.


2. 사용자 정의 예외가 필요한 이유.

  • Java는 프로그래밍 중 발생할 수 있는 일반적인 예외들을 대부분 제공하고 있음.
  • 하지만 실제 개발에서는 기본적으로 제공되는 일반적인 예외들만으로는 아쉬운 점과 불편한 점이 있어서
    사용자 정의 예외를 추가해야 할 필요가 있음.
    • 비즈니스 로직 예외.
      • 특정 업무 규칙이나 프로세스에 맞는 예외를 정의해놓으면 문제의 상황을 더 명확히 이해할 수 있음.
    • 기존 예외의 세분화.
      • 기존에 있는 예외 중 일부 상황만 뽑아내서 별도로 처리할 때 유용함.

2-1. Checked vs Unchecked

  • Java의 Exception은 크게 체크 예외(Checked Exception)언체크 예외(Unchecked Exception)으로 나눔.
    • 체크 예외(Checked Exception)
      • Exception 클래스와 그 자손들.
      • 예외처리 안 하면 컴파일이 안됨.
      • 사용자의 실수처럼 외적인 요인에 의해 발생하는 예외.
    • 언체크 예외(Unchecked Exception)
      • RuntimeException 클래스와 그 자손들.
      • 예외처리가 선택임.
      • 프로그래머의 실수로 인해 발생하는 예외.

2-1-1. (Checked) Ex.

  • 체크(Checked) 예외는 반드시 예외처리를 해야됨.
try (Scanner file = new Scanner(new File(fileName))) {
    if (file.hasNextLine()) return file.nextLine();
} catch(FileNotFoundException e) {
    // 로그 처리 등
}
  • 위처럼 특정 파일의 첫 번째 줄을 읽는 코드가 있을 경우.
    • 해당 코드는 FileNotFoundException을 처리하긴 하지만
      좀 더 세부적으로 "파일이 아예 없는 것인지?" or "파일명이 잘못된 것인지?" 알 수 없음.
  • 따라서 파일 이름이 잘못된 경우를 구분하기 위해 새로운 사용자 정의 예외를 만듦.
public class IncorrectFileNameException extends Exception { 
    public IncorrectFileNameException(String errorMessage) {
        super(errorMessage);
    }
}
  • 위 코드를 아래와 같이 활용할 수 있음.
try (Scanner file = new Scanner(new File(fileName))) {
    if (file.hasNextLine())
        return file.nextLine();
} catch (FileNotFoundException e) {
    if (!isCorrectFileName(fileName)) {
        throw new IncorrectFileNameException("잘못된 파일명: " + fileName );
    }
}
  • 근데 이렇게 작성할 경우 기존의 예외 원인(FileNotFoundException )이 사라져버림.
    • 따라서 이를 보완하려면 생성자에 Throwable을 추가해서 원인 예외를 함께 전달해야됨.
public class IncorrectFileNameException extends Exception { 
    public IncorrectFileNameException(String errorMessage, Throwable err) {
        super(errorMessage, err);
    }
}
  • 그러면 아래와 같이 원인 예외와 함께 던질 수 있음.
catch (FileNotFoundException err) {
    if (!isCorrectFileName(fileName)) {
        throw new IncorrectFileNameException("잘못된 파일명: " + fileName, err);
    }
}

2-2-2. (Unchecked) Ex.

  • 이번에는 파일 이름에 확장자가 아예 없는 경우.
    • 이 문제는 컴파일 시점이 아니라 RuntimeException, 즉 실행중에만 발생하므로 Unchecked 예외가 적절함.
  • 이를 위해 RuntimeException을 상속받아 사용자 정의 예외를 만듦.
public class IncorrectFileExtensionException extends RuntimeException {
    public IncorrectFileExtensionException(String errorMessage, Throwable err) {
        super(errorMessage, err);
    }
}
try (Scanner file = new Scanner(new File(fileName))) {
    if (file.hasNextLine()) {
        return file.nextLine();
    } else {
        throw new IllegalArgumentException("읽을 수 없는 파일");
    }
} catch (FileNotFoundException err) {
    if (!isCorrectFileName(fileName)) {
        throw new IncorrectFileNameException("잘못된 파일명: " + fileName, err);
    }
} catch (IllegalArgumentException err) {
    if (!containsExtension(fileName)) {
        throw new IncorrectFileExtensionException("확장자가 없는 파일명: " + fileName, err);
    }
}

3. 결론.

  • 따라서 사용자 정의 예외는 비즈니스 로직과 밀접한 문제 상황을 명확하게 드러낼 때 매우 유용함.
  • 적절하게 사용한다면 예외 처리와 로깅을 매우 효율적으로 할 수 있음.

4. 참고.

profile
Every cloud has a silver lining.

0개의 댓글