본문 바로가기
카테고리 없음

예외처리2

by 낭만 코딩 2024. 9. 20.

1. 예외 강제 발생

2. 예외 떠넘기기

3. 사용자 정의 예외 클래스

1. 예외 강제 발생

throw 라는 키워드를 사용하면 개발자가 직접 예외를 강제로 발생시킬 수 있습니다.

 

사용방법은

throw new Exception(“예외 발생시 메시지”);

 

package example;

public class ExceptionEx5 {

	public static void main(String[] args) {
		System.out.println("프로그램 시작");
		try {
			throw new Exception("예외 발생");
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		System.out.println("프로그램 종료");
	}
	
}

 

실행 결과

프로그램 시작
예외 발생
프로그램 종료

 

Exception 객체를 생성할 때, 생성자에 문자열 값을 넣어 주면, Exception 객체의 메시지로 저장됩니다. 이 메시지는 getMessage()로 출력할 수 있습니다.

예외를 강제로 발생시키는 코드가 필요한 경우는 보통 비즈니스 로직이 실행되는 도중 특정 상황에 맞지 않아 현재의 로직 실행을 중지시키고, 실행시킨 곳으로 예외를 던져 그에 맞는 처리를 합니다.

 

 

 

2. 예외 떠넘기기

지금까지는 예외를 처리하는 방법으로 try-catch문을 사용했는데, 이 외에 예외를 직접 처리하지 않고 떠넘기는 방법이 있습니다. 메서드의 선언부에 throws 키워드를 사용해서 메서드 내에서 발생할 수 있는 예외를 적어주면 됩니다. 만약 처리해야 할 예외가 여러개라면 ,(콤마)로 구분해서 적어줍니다.

void 메서드명() throws Exception1, Exception2... {
        ...
}

 

throwsthrow가 단어가 비슷해 혼동될 수 있는데, 별개로 구별해서 기억해야 합니다. try~catch문과 throws는 예외를 처리하는 구문이고, throw는 예외를 발생시키는 구문입니다.

package example;

public class ExceptionEx6 {

	public static void main(String[] args) {
		try {
			first();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
	
	static void first() throws Exception {
		second();
	}
	
	static void second() throws Exception {
		throw new Exception("예외 발생");
	}
	
}

 

실행 결과

예외 발생

 

이 예제는 main() 메서드에서 first() 메서드를 호출하고, first() 메서드는 second() 메서드를 호출하는데, second() 메서드에서 예외를 강제로 발생시키고 있습니다. 하지만 직접 예외를 처리하지 않고 메서드 선언부에서 throws를 하고 있기 때문에 first() 메서드로 떠넘긴 것입니다.

그런데 first() 메서드 역시 try~catch문으로 처리하지 않고 예외를 떠넘기고 있습니다. 그래서 main() 메서드에서는 try~catch 문으로 예외를 받아서 출력하고 있습니다. 만약, first() 메서드에서 throws를 하지 않거나, main() 메서드에서 try~catch문으로 처리하지 않으면 컴파일 에러가 발생합니다.

던져진 예외를 반드시 try~catch문으로 처리하던지 또 다시 떠넘기던지 해야합니다.

 

이렇게 메서드에서 예외를 떠넘기는 것이 나쁜것만은 아닙니다. 오히려 메서드 선언부에 예외 클래스를 적어주기 때문에 코드를 해석할 때 '이 메서드는 어느어느 예외가 발생하겠구나'라고 미리 예측할 수 있기 때문에 예외 발생에 대한 보다 안전한 프로그래밍을 할 수 있게 되기도 합니다.

 

이전 예제들에서 보았던 Integer.parseInt() 라는 메서드를 확인해볼까요. 이클립스에서 ctrl+클릭해보면 해당 메서드로 이동되며, 내용을 확인할 수 있습니다.

자바에서 기본 제공되는 java.lang 패키지 안에 있는 Integer 클래스의 parseInt() 메서드 실제 코드입니다. 메서드 선언부에 throws NumberFormatException이 정의되어 있는것을 알 수 있습니다. 우리는 이것을 보고 이 메서드는 이 예외가 발생할 수 있구나 하는 것을 알 수 있고, 또한 반드시 처리해줘야하는 예외이므로 내부 코드를 다 뒤져보지 않아도 미리 예상하고 준비할 수 있는 코드를 작성할 수 있게 되는 것입니다.

 

 

 

3. 사용자 정의 예외 클래스

이미 자바에서 제공하는 예외 클래스 외에 개발자가 직접 새로운 예외 클래스를 정의해서 사용할 수 있는데, Throwable 클래스나 그 하위 클래스로부터 상속받아 사용자 정의 예외 클래스를 생성합니다. 보통 Exception 클래스로부터 상속받아 클래스를 만드는 경우가 많습니다.

 

class 클래스명 extends Exception {
    클래스명 (String msg) {
        super(msg);
    }
}

 

위 예제는 Exception 클래스를 상속받아 클래스를 정의했습니다. 추가로 변수나 메서드도 정의할 수 있습니다. 생성자는 매개변수를 통해 메시지를 입력받아 상위 클래스(Exception)의 생성자로 메시지를 매개변수로 넘겨주며 실행합니다.(super() : 부모 생성자)

 

LoginException.java

package example;

public class LoginException extends Exception {

	LoginException(String msg) {
		super(msg);
	}
}

 

Exception8.java

package example;

import java.util.Scanner;

public class ExceptionEx8 {
	
	static String user_id = "abc";
	static String user_pw = "abc1234";

	public static void main(String[] args) throws Exception {
		
		try {
			Scanner scan = new Scanner(System.in);
			System.out.print("아이디 : ");
			String input_id = scan.nextLine();
			
			System.out.print("비밀번호 : ");
			String input_pw = scan.nextLine();
			
			if (!user_id.equals(input_id)) {
				throw new LoginException("아이디가 올바르지 않습니다.");
			} else if (!user_pw.equals(input_pw)) {
				throw new LoginException("비밀번호가 올바르지 않습니다.");
			} else {
				System.out.println("로그인 성공");
			}
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		
	}
}

 

실행 결과

아이디 : test
비밀번호 : test1234
아이디가 올바르지 않습니다.

 

LoginException.java 파일은 Exception 클래스를 상속받아 정의한 사용자 정의 예외 클래스입니다.

ExceptionEx8.java 파일은 Scanner라는 클래스를 이용해서 이클립스의 콘솔창에 직접 값을 입력받아 프로그램 내에서 처리하는 예제입니다.

"아이디 : " 문자열을 콘솔창에 출력 후 사용자가 아이디를 입력할 때까지 프로그램은 대기하게 됩니다. 콘솔창에 값을 입력 후 엔터를 치면 다음 실행문으로 넘어갑니다. 다음비밀번호 : ” 문자열 출력 후 역시 사용자가 비밀번호를 입력할 때까지 대기한 후 값이 입력되면 다음 실행문으로 넘어갑니다.

마지막으로 if문은 사용자가 입력한 아이디와 비밀번호를 클래스의 멤버변수와 비교하는 구문으로 값이 일치하지 않으면 위에서 정의한 LoginException 클래스를 통해 예외 메시지를 전달하며 강제로 예외를 발생시킵니다. 이 실행문들이 main() 메서드 내에서 try~catch문으로 예외가 처리되고 있으므로 LoginException 예외가 발생하면 메시지를 출력하게 됩니다. 위 실행 결과는 아이디를 "test", 비밀번호를 "test1234"로 입력하여 예외가 발생하였는데, "abc", "abc1234"로 입력하면 "로그인 성공"이라는 문자열이 출력됩니다.