예외 던지기
예외 발생시키기 (throw)
만일 프로그램적으로 에러가 아니라도 로직상 개발자가 일부러 에러를 내서 로그에 기록하고 싶은 상황이 올 수 있다.
자바에서는 throw 키워드를 사용하여 강제로 예외를 발생시킬 수 있다.
원래는 프로그램이 알아서 에러를 탐지하고 처리 하였지만, 이번에는 사용자가 일부러 에러를 throw하여 에러를 catch 한다는 개념으로 보면 된다.
이 때 new 생성자로 예외 클래스를 초기화하여 던지는데, 이 클래스 생성자에 입력값을 주게 되면, catch의 getMessage() 메서드에서 출력할 메세지를 지정하게 된다.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
try {
Scanner s = new Scanner(System.in);
System.out.print("음수를 제외한 숫자만 입력하세요 : ");
int num = s.nextInt();
if (num < 0) {
// 만일 사용자가 말을 안듣고 음수를 입력하면 강제로 에러 발생 시키기
throw new ArithmeticException("음수 안돼요");
}
System.out.println("음수를 입력하지 않으셨군요. 감사합니다");
} catch (ArithmeticException e) {
System.out.println(e.getMessage());
} finally {
System.out.println("프로그램을 종료합니다");
}
}
}
예외 떠넘기기 (throws)
예외가 발생할 수 있는 코드를 작성할 때 try-catch 블록으로 처리하는 것이 기본이지만, 경우에 따라서는 다른 곳에서 예외를 처리하도록 호출한 곳으로 예외를 떠넘길 수도 있다.
이때 사용하는 키워드가 throws 이다. throws는 메소드 선언부 끝에 작성되어 메소드에서 예외를 직접 처리(catch) 하지 않은 예외를 호출한 곳으로 떠넘기는 역할을 한다.
예외를 발생시키는 키워드는 throw고 예외를 메서드에 선언하는 키워드는 throws 이다.
예를 들어 다음과 같이 메서드 3개가 있고 각 메서드 마다 예외 처리를 위해 try - catch 블록으로 일일히 감싸주었다.
public class Main {
public static void main(String[] args) {
method1();
method2();
method3();
}
public static void method1() {
try {
throw new ClassNotFoundException("에러이지롱");
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}
}
public static void method2() {
try {
throw new ArithmeticException("에러이지롱");
} catch (ArithmeticException e) {
System.out.println(e.getMessage());
}
}
public static void method3() {
try {
throw new NullPointerException("에러이지롱");
} catch (NullPointerException e) {
System.out.println(e.getMessage());
}
}
}
하지만 괜히 코드가 길어지고 가독성도 그렇게 좋지가 않아 보인다.
다음과 같이 메서드 선언 코드 오른쪽에 throws 예외클래스명 을 기재해주면, 만일 해당 메서드 안에서 예외가 발생할 경우 try - catch 문이 없으면 해당 메서드를 호출한 상위 스택 메서드로 가서 예외 처리를 하게 된다.
void method() throws Exception, Exception2, ... {
에러발생코드; // 예외가 발생하면 현 메소드를 호출한 쪽으로 올라간다.
}
public class Main {
public static void main(String[] args) {
try {
method1();
method2();
method3();
} catch (ClassNotFoundException | ArithmeticException | NullPointerException e) {
System.out.println(e.getMessage());
}
}
public static void method1() throws ClassNotFoundException {
throw new ClassNotFoundException("에러이지롱");
}
public static void method2() throws ArithmeticException {
throw new ArithmeticException("에러이지롱");
}
public static void method3() throws NullPointerException {
throw new NullPointerException("에러이지롱");
}
}
즉, 예외클래스를 메서드의 throws에 명시하는 것은 이곳에서 예외를 처리하는 것이 아니라 자신을 호출한 메서드에게 예외를 전달하여 예외 처리를 떠맡기는 것이다. 또한 예외를 전달받은 메서드가 또 다시 자신을 호출한 메서드에게 전달할 수 있다. 이런 식으로 계속 호출 스택에 있는 메서드들을 따라 전달되다가, 제일 마지막에 있는 main 메소드에서 throws를 사용하면 가상머신에서 처리된다.
'Study > WEB' 카테고리의 다른 글
[Java] 빠져나올 수 없는 null 처리의 늪 - 2 (0) | 2023.02.08 |
---|---|
[Java] 빠져나올 수 없는 null 처리의 늪 - 1 (2) | 2023.02.06 |
[WEB] HTTP Method (0) | 2023.01.26 |
좋은 객체 지향 설계의 5가지 원칙 (SOLID) (0) | 2023.01.24 |
[WEB] WebSocket 이란? (0) | 2023.01.13 |