Java에서는 애플리케이션의 비즈니스 로직에 맞는 자신만의 예외를 직접 정의하는 것이 좋습니다. 사용자 정의 예외를 활용하면 오류의 원인을 더 명확하게 드러낼 수 있고, 예외 객체에 추가 정보를 담아 전달할 수 있어 디버깅과 유지보수가 한결 수월해집니다. 표준 예외만으로는 표현하기 어려운 도메인 특화 오류(예: 잔액 부족, 잘못된 계좌 번호 등)가 있다면 사용자 정의 예외를 만들 가치가 충분합니다.
사용자 정의 예외 클래스 작성 시 유의 사항
- 모든 예외 클래스는 반드시
Throwable의 하위 클래스여야 합니다. - Handle 또는 Declare 규칙(예외를 처리하거나
throws로 선언)에 따라 컴파일러가 자동으로 강제하는 체크드 예외(checked exception)를 만들려면Exception클래스를 확장해야 합니다. - 컴파일러가 강제하지 않는 런타임 예외(runtime exception)를 만들려면
RuntimeException클래스를 확장해야 합니다.
예외 클래스 정의 방법
자신만의 예외 클래스를 정의하는 방법은 매우 간단합니다. Exception 클래스를 확장하기만 하면 됩니다.
class MyException extends Exception {
}
Exception을 확장한 예외는 체크드 예외로 간주됩니다. 아래의 InsufficientFundsException 클래스는 Exception 클래스를 상속한 사용자 정의 예외로, 계좌 잔액이 부족한 상황을 나타내는 체크드 예외입니다.
예제: 은행 계좌 출금 시나리오
// 파일명: InsufficientFundsException.java
import java.io.*;
class InsufficientFundsException extends Exception {
private double amount;
public InsufficientFundsException(double amount) {
this.amount = amount;
}
public double getAmount() {
return amount;
}
}
// 파일명: CheckingAccount.java
class CheckingAccount {
private double balance;
private int number;
public CheckingAccount(int number) {
this.number = number;
}
public void deposit(double amount) {
balance += amount;
}
public void withdraw(double amount) throws InsufficientFundsException {
if(amount <= balance) {
balance -= amount;
} else {
double needs = amount - balance;
throw new InsufficientFundsException(needs);
}
}
public double getBalance() {
return balance;
}
public int getNumber() {
return number;
}
}
// 파일명: BankDemo.java
public class BankDemo {
public static void main(String [] args) {
CheckingAccount c = new CheckingAccount(101);
System.out.println("Depositing $500...");
c.deposit(500.00);
try {
System.out.println("\nWithdrawing $100...");
c.withdraw(100.00);
System.out.println("\nWithdrawing $600...");
c.withdraw(600.00);
} catch(InsufficientFundsException e) {
System.out.println("Sorry, but you are short $" + e.getAmount());
e.printStackTrace();
}
}
}
실행 결과
Depositing $500... Withdrawing $100... Withdrawing $600... Sorry, but you are short $200.0 InsufficientFundsException at CheckingAccount.withdraw(BankDemo.java:32) at BankDemo.main(BankDemo.java:53)
정리
위 예제에서 withdraw() 메서드는 잔액이 부족할 때 throws 절을 통해 InsufficientFundsException을 던지고, 호출자인 main()은 try-catch 블록으로 이를 처리합니다. 사용자 정의 예외는 단순히 오류 발생 사실만 알리는 데 그치지 않고, getAmount() 메서드처럼 부족한 금액과 같은 구체적인 정보를 함께 전달할 수 있다는 점이 큰 장점입니다. 이를 통해 호출자는 예외를 더 정확하게 판단하고, 최종 사용자에게도 의미 있는 피드백을 제공할 수 있습니다.