[Java] 예외 처리 ②

kiteB·2022년 1월 28일
0

Java

목록 보기
26/35
post-thumbnail

[ 예외 처리 코드 ]

프로그램에서 예외가 발생했을 경우 프로그램의 갑작스러운 종료를 막고, 정상 실행을 유지할 수 있도록 처리하는 코드를 예외 처리 코드라고 한다.


1. 예외 처리

예외 처리는 try-catch-finally 블록을 이용한다.
try-catch-finally 블록은 생성자 내부와 메소드 내부에서 작성되어 일반 예외와 실행 예외가 발생할 경우 예외 처리를 할 수 있도록 해준다.

try {
    예외를 처리하길 원하는 실행 코드;
} catch (e1) {
    e1 예외가 발생할 경우에 실행될 코드;
} catch (e2) {
    e2 예외가 발생할 경우에 실행될 코드;
}
...
finally {
    예외 발생 여부와 상관없이 무조건 실행될 코드;
}
  • try 블록: 예외 발생 코드가 위치한다. 여기에서 발생한 예외는 catch 블록에서 처리된다.
  • catch 블록: try 블록에서 발생한 예외 코드나 예외 객체를 인수로 전달받아 그 처리를 담당한다.
  • finally 블록: try 블록에서 예외 발생 여부와 상관없이 항상 실행한다.
    • finally 블록은 옵션으로 생략 가능하다.
    • try 블록과 catch 블록에서 return문을 사용하더라도 finally 블록은 항상 실행된다.

사용할 수 있는 모든 적합한 try 구문은 다음과 같다.

1. try / catch
2. try / finally
3. try / catch / ... / finally

2. 예외 처리 매커니즘

자바에서 예외 처리는 다음과 같은 순서로 진행된다.

  1. try 블록에 도달한 프로그램의 제어는 try 블록 내의 코드를 실행한다.
    이때 만약 예외가 발생(throw)하지 않고, finally 블록이 존재하면 프로그램의 제어는 바로 finally 블록으로 이동한다.

  2. try 블록에서 예외가 발생하면 catch 핸들러는 다음과 같은 순서로 적절한 catch 블록을 찾는다.
    2-1. 스택에서 try 블록과 가장 가까운 catch 블록부터 차례대로 검사한다.
    2-2. 만약 적절한 catch 블록을 찾지 못하면, 바로 다음 바깥쪽 try 블록 다음에 위치한 catch 블록을 차례대로 검사한다.
    2-3. 이러한 과정을 가장 바깥쪽 try 블록까지 계속 검사한다.
    2-4. 그래도 적절한 catch 블록을 찾지 못하면, 예외는 처리되지 못한다.

  3. 만약 적절한 catch 블록을 찾게 되면, throw 문의 피연산자는 예외 객체의 형식 매개변수로 전달된다.

  4. 모든 예외 처리가 끝나면 프로그램의 제어는 finally 블록으로 이동한다.

  5. finally 블록이 모두 처리되면, 프로그램의 제어는 예외 처리문 바로 다음으로 이동한다.


[ 예외 종류에 따른 처리 코드 ]

1. 다중 catch

try 블록 내부는 다양한 종류의 예외가 발생할 수 있는데, 이럴 때 다중 catch 블록을 작성한다.


catch 블록이 여러 개라고 할지라도 단 하나의 catch 블록만 실행된다. 그 이유는 try 블록에서 동시 다발적으로 예외가 발생하지 않고, 하나의 예외가 발생하면 즉시 실행을 멈추고 해당 catch 블록으로 이동하기 때문이다.

예제

public class CatchByExceptionKindExample {
    public static void main(String[] args) {
        try {
            String data1 = args[0];
            String data2 = args[1];
            int value1 = Integer.parseInt(data1);
            int value2 = Integer.parseInt(data2);
            int result = value1 + value2;
            System.out.println(data1 + "+" + data2 + "=" + result);
        } catch(ArrayIndexOutOfBoundsException e) {
            System.out.println("실행 매개값의 수가 부족합니다.");
            System.out.println("[실행 방법]");
            System.out.println("java CatchByExceptionKindExample    num1    num2");
        } catch(NumberFormatException e) {
            System.out.println("숫자로 변환할 수 없습니다.");
        } finally {
            System.out.println("다시 실행하세요.");
        }
    }

}
  • 실행 결과
실행 매개값의 수가 부족합니다.
[실행 방법]
java CatchByExceptionKindExample    num1    num2
다시 실행하세요.
  • 4, 5 라인에서 ArrayIndexOutOfBoundsException이 발생한다면 11~13라인이 실행되고,
  • 6, 7라인에서 NumberFormatException이 발생한다면 15라인이 실행된다.
  • 17라인은 예외 발생 여부와 상관없이 실행된다.

2. catch 순서

다중 catch 블록을 작성할 때 주의할 점은 상위 예외 클래스가 하위 예외 클래스보다 아래쪽에 위치해야 한다는 것이다!

try 블록에서 예외가 발생했을 때, 예외를 처리해줄 catch 블록은 위에서부터 차례대로 검색된다.
만약 상위 예외 클래스의 catch 블록이 위에 있다면, 하위 예외 클래스의 catch 블록은 실행되지 않는다.

위와 같이 코드를 작성하면 ArrayIndexOutOfBoundsException, NumberFormatExceptionException을 상속받기 때문에 첫 번째 catch 블록만 실행된다.

그래서 ArrayIndexOutOfBoundsException인 경우, ArrayIndexOutOfBoundsException에 해당하는 예외 처리 코드를 실행시키고 싶다면 다음과 같이 코드를 수정해야 한다.


3. 멀티 catch

자바 7부터 하나의 catch 블록에서 여러 개의 예외를 처리할 수 있도록 멀티 catch 기능을 추가하였다.

catch 괄호 안에 동일하게 처리하고 싶은 예외를 |로 연결하면 된다.


[ 참고자료 ]

이것이 자바다 책
http://tcpschool.com/java/java_exception_intro

profile
🚧 https://coji.tistory.com/ 🏠

0개의 댓글