Java의 예외 처리 흐름

상곤·2025년 4월 19일

Java

목록 보기
20/22
post-thumbnail
public class Main {
    public static void main(String[] args) {
        int sum = 0;

        try {
            func();
        } catch (NullPointerException e) {
            sum += 1;
        } catch (Exception e) {
            sum += 10;
        } finally {
            sum += 100;
        }

        System.out.println(sum);
    }

    static void func() throws Exception {
        throw new NullPointerException();
    }
}

위 코드의 결과가 어떻게 될까?

Java를 배운지 얼마 안 됐으면,
이 구조가 익숙하지 않을 것이다.

일반적인 함수는 반환형을 명시하고,
반환형에 맞게 return으로 값을 돌려주는 구조다.

반환된 값을 대입하거나, 조건문(if) 등으로 분기해서 처리하는 경우가 많다.

그런데 여기는 반환형도 void라서 없고,
일반적으로 알고 있는 조건문(if문)도 없다.

그래서 헷갈리는 것이다.
try-catch-finally 블록에서는 먼저 try 부분이 실행된다.
try 블록 안에서 func() 함수를 호출하고,
이때 throw new로 예외를 던지면,
catch 블록해당 예외를 받아서 처리한다.

catch 블록에 명시된 예외 타입과 일치하는 예외가 없어 예외를 처리하지 못하더라도,
finally 블록은 무조건 실행된다.

그래서 이 코드의 흐름을 따라가보면 이렇다.

1. `try` 블록에서 `func()` 호출
2. `func()` 내부에서 `throw new NullPointerException()` 발생
3. `try`에서 던진 예외를 `catch (NullPointerException e)`가 받음
4. `catch` 블록 실행 → `sum += 1`
5. 이후 **무조건 실행되는** `finally` 블록 실행 → `sum += 100`
6. 최종적으로 `sum == 101` 출력

코드에다가 주석을 달아서 살펴보면 이렇다.

public class Main {
    public static void main(String[] args) {
        int sum = 0;
        
        // try - catch - finally Block 시작
        try {
            func(); // 1. func() 호출 중 예외 발생 → catch 블록으로 이동
        } catch (NullPointerException e) { // 2. 맞는 catch 블록 실행
            sum = sum + 1;
        } catch (Exception e) {
            sum = sum + 10;
        } finally { // 3. (catch 끝나고) finally 블록 무조건 실행
            sum = sum + 100;
        }
        // try - catch - finally Block 끝

        System.out.print(sum); // 4. 프로그램 계속 진행, 최종 출력
    }

    static void func() throws Exception {
        throw new NullPointerException(); // 0. 예외 발생
    }
}

그래서 최종 출력은 101이 된다!

예외가 발생해도 finally는 무조건 실행되는 걸 기억하자!

profile
🫠

0개의 댓글