본문 바로가기

사용자 정의 예외

게임 프로그램에서 상점에서 아이템을 구매할 때 아이템의 금액보다 사용자의 보유액이 적은 경우 예외를 발생시킬 필요가 있다. 그런데 이런 예외는 자바에서 제공하지 않는다. 어떻게 해야 할까?


이런 예외를 애플리케이션 예외(Application exception)이라 한다. 애플리케이션 예외는 사용자가 직접 정의해야 하므로 사용자 정의 예외라고도 한다.


사용자 정의 예외는 일반 예외로 선언할 수도 있고 실행 예외로 선언할 수도 있다. 전자의 경우  Exception 클래스를, 후자의 경우  RuntimeException  클래스를 상속하면 된다. 이 때 사용자 정의 예외 클래스의 이름은 다음과 같이 Exception으로 끝나는 게 좋다. 


public class XXXException extends Exception {

    public XXXException() {}

    public XXXException(String message) { super(message); }

}


사용자 정의 예외 클래스 역시 여타 클래스와 마찬가지로 필드, 생성자, 메소드를 포함할 수 있지만, 생성자 선언만을 포함하는 것이 일반적이다.

생성자는 보통 기본 생성자와 예외의 원인에 대한 메시지를 전달하기 위한 String 매개변수를 갖는 생성자다. 후자의 경우 상위 클래스(Exception, RuntimeException)에 예외 메시지를 넘겨주는데, 이는 catch 블록에서 사용하기 위함이다.


다음은 보유액 부족 예외 클래스다.


1
2
3
4
5
6
7
8
9
10
public class LackOfRetentionException extends Exception {
 
    public LackOfRetentionException() {
    }
 
    public LackOfRetentionException(String message) {
        super(message);
    }
    
}
cs


 LackOfRetentionException 은  Exception  클래스를 상속하고 있기 때문에 컴파일러에 의해 체크된다. 따라서 코드 작성 시  try-catch  블록에 의한 예외 처리가 필요하다.


앞서 선언한 LackOfRetentionException 은 특수한 경우에 발생하는 예외다. 때문에 원하는 시점에 예외를 발생시켜야 하는데, 예외를 발생시키는 방법은 다음과 같다.


throw new LackOfRetentionException();

throw new LackOfRetentionException("MESSAGE");


메시지는 필요에 따라 줄 수도, 주지 않을 수도 있다.

예외 발생 코드를 갖고 있는 메소드는 내부에서 try-catch 블록으로 처리할 수도 있지만,

자신을 호출한 곳에서 처리하도록 떠넘기는(throws) 형태가 일반적이다.


다음은 아이템을 구매하는 메소드가 포함된 사용자 클래스다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class User {
    private long retention = 0;
 
    public long getRetention() { return retention; }
    public void setRetention(long retention) { this.retention = retention; }
    
    public void purchase(long price) throws LackOfRetentionException {
        System.out.println("선택하신 상품의 가격은 " + price +"원입니다.");
        System.out.println("현재 보유액은 " + retention + "원입니다.");
        
        if(retention < price) {
            throw new LackOfRetentionException("구매 불가 - 보유액 부족: " + (price - retention) + "이 모자랍니다.");
        } else {
            retention -= price;
            System.out.println("구매 성공");
        }        
    }
    
}
cs



이제 이 메소드를 실행해보자.


1
2
3
4
5
6
7
8
9
10
11
12
public class Example {
    public static void main(String[] args) {
        User user = new User();
        long price = 3000;
        
        try {
            user.purchase(price);
        } catch(LackOfRetentionException e) {
            e.printStackTrace();
        }
    }
}
cs



전달한 오류 메시지과 스택 트레이스가 출력된 것을 확인할 수 있다.

스택 트레이스를 보면 User.java의 14번째 줄에서 최초로 예외가 발생했고, 그 예외가 Example.java의 10번째 줄로 떠넘겨졌음을(throw 되었음을) 알 수 있다.



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

압축파일탐색기  (0) 2021.03.11
예외 처리  (0) 2019.07.06
JVM  (0) 2019.07.04
Managed code  (0) 2019.07.04
IO 입출력  (0) 2019.05.23