Exception handling (예외 처리)

hyunwoo·2023년 1월 22일
0

🌳 Java 지식

목록 보기
16/21

참고: https://day0404.tistory.com/47

try catch 문법

자바에서 기본적인 예외처리는 아래와 같이 try catch 문법을 통해 진행합니다.

try {
	// 실행되어야 할 로직
} catch (예외 클래스) {
	// 예외처리 코드
} finally {
	// 예외와 관계없이 무조건 실행되는 코드
}
  • try 블록에 실제 실행되어야 하는 코드가 들어가며 Exception이 발생할 가능성이 있는 코드가 들어갑니다.
  • catch 블록에는 Exception이 발생하면 실행되는 코드가 들어갑니다. 즉 예외처리를 하는 코드입니다.
  • finally 블럭에는 어떠한 예외가 발생하더라도 반드시 실행되어야 하는 코드가 들어가는 곳입니다.

코드를 아주 완벽하게 작성한다면 예외가 발생할 수 있는 상황이 줄어들 수는 있지만,
사용자가 개발자의 의도와 다른 행동을 하여 예외가 발생하는 경우 미리 해당 상황에 대해 예외처리를 해줄 수 있습니다.
그렇게 하여 프로그램이 예기치 못한 상황에서 비정상적으로 종료되는 것을 막고 정상적으로 작동하게 할 수 있습니다.


2를 0으로 나눌 수 없기 때문에 오류가 발생하게 됩니다.
이 코드를 다시 try catch 문을 통해 예외 처리하면 다음과 같습니다.

public class Test {
    public static void main(String[] args) {
        int a = 2;
        int b = 0;
        try {
            int c = a / b;
        } catch (ArithmeticException e) {
            e.printStackTrace();
        } finally {
            System.out.println("finally");
        }
    }
}

printStackTrace() 메서드의 경우 어느 부분에서 예외가 발생했는지 로그를 보여줍니다.

위 코드를 실행시키면 아래와 같습니다.

처음에 예외 처리하지 않고 실행시킨 결과와 다를 게 없어 보입니다.
printStackTrace로 예외의 로그를 확인하게만 해뒀기 때문에 그렇습니다.


참고: https://wonyong-jang.github.io/java/2020/07/27/Java-throws-throw.html

예외 던지기 (throw, throws)

  • throw : 에러를 고의로 발생시킬 때 사용합니다.
  • throws : 자신을 호출한 상위 메소드로 에러를 던지는 역할을 합니다.

throw

일단 throw의 경우 개발자가 의도적으로 예외를 발생시키는 것입니다.

throw라는 키워드를 이용하며, 주로 비즈니스 로직을 구현하는 과정 중 컴파일에는 문제가 없지만 해당 비지니스 로직이 개발자가 의도한 대로 통과하지 못했을 경우 고의로 예외를 발생시켜야 할 때 사용합니다.

public class Test {
    public static void main(String[] args) {
        int a = 2;
        int b = 0;
        divide(a, b);
    }

    public static int divide(int a, int b) {
        if (b == 0) {
            throw new ArithmeticException("0으로 나눌 수 없습니다.");
        }
        return a / b;
    }
}

물론 위 코드는 제가 throw를 사용하지 않아도 예외가 발생하게 됩니다.
만약 인자 값 a가 2인 경우 throw 키워드를 통해 강제로 예외 발생시킬 수도 있습니다.

이처럼 throw 키워드를 사용하면 개발자의 판단에 따라 강제로 예외를 발생시킬 수 있습니다.

throws

throws의 경우 메서드 내에서 예외처리를 하지 않고 해당 메서드를 사용한 곳에서 예외 처리를 하도록 예외를 위로 던지는 것입니다. 예외를 전가하는 것 입니다.

public class Test {
    public static void main(String[] args) {
        int a = 2;
        int b = 0;
        try {
            divide(a, b);
        } catch (ArithmeticException e) {
            e.printStackTrace();
        }
    }

    public static int divide(int a, int b) throws ArithmeticException {
        if (b == 0) {
            throw new ArithmeticException("0으로 나눌 수 없습니다.");
        }
        return a / b;
    }
}


divide 메서드는 예외를 자신이 처리하지 않고 throws 키워드를 통해 자신을 호출한 main 메서드에게 책임을 전가했습니다.

그래서 이 divide 메서드를 호출한 main 메서드에서 try catch 문을 통해 예외처리를 진행했습니다.


정리하자면 throw는 강제로 예외를 발생시키는 것이며 개발자의 판단에 따른 처리가 가능합니다.
throws는 자신을 호출한 메서드에게 책임을 전가하여 호출한 메서드에서 예외처리를 하도록 강요합니다.

throw를 사용하는 이유는 예외가 발생할 수 있는 코드가 있다는 것을 인지시키고 예외처리를 강요하며, 여러 가지 발생 가능한 예외들을 호출한 메서드에서 한 번에 처리할 수 있게 하여 관리를 용이하게 해 줄 수 있습니다.

예제1

public class Test {
    public static void main(String[] args){
        try {
            onAction();
        } catch (Exception e){
            System.out.println("onAction에서 6을 발견했나 봅니다.");
        } finally {
            System.out.println("try-catch문을 종료하고 finally 문을 처리합니다.");
        }
    }

    public static void onAction() throws Exception {
        for(int i=0; i<10; i++){
            try {
                if(i!=6){
                    System.out.println(i+ "는 6이 아닙니다");
                } else{
                    throw new Exception();
                }
            } catch(Exception e) {
                System.out.println(i+"는 6이 맞네요. CheckException on Action() 메서드 안에서 발생");
                throw e;
            }
        }
    }
}

실행순서
1. main의 try문에서 onAction() 메서드 호출
2. onAction()의 for문 내에서 try-catch문으로 i==6일 때 Check6Exception()을 발생(throw 사용)
3. catch문을 통해 예외처리 및 exception 정보를 현재 메서드로 전달할 수 있다.(throw e)
4. throws 키워드를 통해 3.에서 전달한 exception 정보를 main()으로 전달하여 main()의 catch()문 수행
5. finally() 수행

다시 보면 throw를 통해 발생한 exception을 catch에서 발견한 경우 더이상의 exception에 대한 정보는 존재하지 않는다. 하지만 catch문에서 다시 throw를 통한 인위적인 exception을 발생시켰고,
이를 onAction() 메서드가 받아서 상위 메서드인 main()으로 전달하게 된다.
따라서 catch문의 마지막에 exception을 추가로 발생시킨 경우 onAction()에 throws 키워드를 사용하지 않으면 컴파일 에러가 발생한다.

0개의 댓글