백엔드/Java

예외처리

Ryuzy 2025. 5. 20. 23:25
728x90
반응형

1. 예외처리

예외처리(Exception Handling)란 프로그램 실행 중 발생할 수 있는 오류 상황을 미리 대비하여 프로그램이 비정상적으로 종료되지 않도록 처리하는 방법입니다. 예외가 발생할 수 있는 코드를 try 블록에 작성하고, 오류 발생 시 실행할 코드를 catch 블록에 작성함으로써 예외를 안전하게 처리할 수 있습니다. 필요에 따라 finally 블록을 사용하여 예외 발생 여부와 상관없이 반드시 실행해야 하는 코드를 넣을 수 있으며, 개발자는 throw 키워드를 사용해 명시적으로 예외를 발생시킬 수도 있습니다. 예외처리는 사용자 경험 향상과 안정적인 프로그램 유지에 필수적인 기능입니다.

 

 

2. 예외의 종류

Checked Exception 컴파일 시 예외처리를 강제 IOException, SQLException 등
Unchecked Exception 실행 중 발생, 컴파일러가 체크하지 않음 NullPointerException, ArithmeticException, ArrayIndexOutOfBoundsException 등

 

 

3. 예외 처리 구문

try {
    // 예외가 발생할 수 있는 코드
} catch (ExceptionType e) {
    // 예외 발생 시 처리 코드
} finally {
    // 예외 발생 여부와 무관하게 항상 실행 (선택 사항)
}

 

public class Example1 {
    public static void main(String[] args) {
        try {
            int result = 10 / 0; // 0으로 나누기 → 예외 발생
            System.out.println("결과: " + result);
        } catch (ArithmeticException e) {
            System.out.println("예외 발생: " + e.getMessage());
        } finally {
            System.out.println("이 코드는 항상 실행됩니다.");
        }
    }
}

 

public class Example2 {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3};

        try {
            System.out.println(numbers[5]); // 존재하지 않는 인덱스
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("배열 범위를 벗어났습니다: " + e);
        }
    }
}

 

public class Example3 {
    public static void main(String[] args) {
        try {
            String s = null;
            System.out.println(s.length());  // NullPointerException
        } catch (ArithmeticException e) {
            System.out.println("산술 오류: " + e.getMessage());
        } catch (NullPointerException e) {
            System.out.println("널 오류: " + e.getMessage());
        } catch (Exception e) {
            System.out.println("기타 오류: " + e.getMessage());
        }
    }
}

 

import java.util.Scanner;

public class DivisionCalculator {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        try {
            System.out.println("=== 나눗셈 계산기 ===");
            System.out.print("첫 번째 숫자를 입력하세요: ");
            int a = scanner.nextInt();

            System.out.print("두 번째 숫자를 입력하세요: ");
            int b = scanner.nextInt();

            int result = a / b;  // b가 0이면 예외 발생
            System.out.println("결과: " + a + " ÷ " + b + " = " + result);
        } catch (ArithmeticException e) {
            System.out.println("오류: 0으로 나눌 수 없습니다!");
        } catch (Exception e) {
            System.out.println("예기치 못한 오류 발생: " + e.getMessage());
        } finally {
            System.out.println("계산기를 종료합니다. 이용해주셔서 감사합니다.");
            scanner.close();
        }
    }
}

 

 

4. 예외 던지기

자바에서 예외가 발생한 상황을 직접 명시적으로 알리고 처리 흐름을 넘기는 방법입니다. 예외가 발생하면, 자바는 해당 예외 객체를 만들어서 던지고(throw), 호출한 쪽은 그 예외를 받아서 처리하거나 다시 위로 넘겨야 합니다. 이때 사용하는 키워드가 바로 throw와 throws입니다.

1. throw 키워드

  • throw는 실제 예외 객체를 생성해서 직접 던질 때 사용합니다.
  • 주로 if 문에서 조건에 따라 예외를 발생시킬 때 사용합니다.
throw new 예외클래스("메시지");

 

public class ThrowExample {
    public static void checkAge(int age) {
        if (age < 18) {
            throw new IllegalArgumentException("18세 미만은 접근할 수 없습니다.");
        }
        System.out.println("접근 허용");
    }

    public static void main(String[] args) {
        checkAge(15);  // 예외 발생!
    }
}

 

2. throws 키워드

  • throws는 예외를 현재 메서드에서 직접 처리하지 않고, 호출한 쪽으로 넘기겠다고 선언할 때 사용합니다.
  • 주로 Checked Exception(컴파일러가 검사하는 예외)에 사용합니다.
리턴타입 메서드이름() throws 예외클래스 {
    // 예외 발생 코드
}

 

// 예외를 던질 수 있는 메서드
public class ThrowsExample {
    public static double calculateSqrt(int number) throws IllegalArgumentException {
        if (number < 0) {
            throw new IllegalArgumentException("음수는 제곱근을 계산할 수 없습니다.");
        }
        return Math.sqrt(number);
    }

    public static void main(String[] args) {
        try {
            double result = calculateSqrt(-9);  // 예외 발생!
            System.out.println("결과: " + result);
        } catch (IllegalArgumentException e) {
            System.out.println("예외 발생: " + e.getMessage());
        }
    }
}
  • calculateSqrt(int number) 메서드는 throws IllegalArgumentException을 통해 예외를 직접 처리하지 않고 위임합니다.
  • main() 메서드에서 try ~ catch를 사용하여 예외를 실제로 처리합니다.
  • IllegalArgumentException은 Unchecked Exception이지만 throws와 함께 사용할 수 있습니다.

 

 

5. 사용자 정의 예외

기본 제공하는 예외 클래스(예: NullPointerException, IOException 등) 외에, 개발자가 직접 만든 예외 클래스입니다. 특정 상황에 대해 명확하게 예외를 구분하거나, 의미 있는 이름과 메시지로 예외를 전달하고 싶을 때 사용합니다.

만드는 방법

  • Exception 또는 RuntimeException을 상속받습니다.
  • 생성자에서 super(메시지)를 호출해 부모 생성자에게 메시지를 전달합니다.

1. Checked 사용자 정의 예외 (Exception 상속)

public class CustomExceptionExample {
    public static void checkScore(int score) throws InvalidScoreException {
        if (score < 0 || score > 100) {
            throw new InvalidScoreException("점수는 0에서 100 사이여야 합니다.");
        }
        System.out.println("유효한 점수입니다: " + score);
    }

    public static void main(String[] args) {
        try {
            checkScore(150);  // 예외 발생
        } catch (InvalidScoreException e) {
            System.out.println("예외 처리됨: " + e.getMessage());
        }
    }
}

 

2. Unchecked 사용자 정의 예외 (RuntimeException 상속)

public class RuntimeCustomExceptionExample {
    public static void validateUsername(String name) {
        if (name == null || name.isEmpty()) {
            throw new InvalidUserException("사용자 이름은 비어 있을 수 없습니다.");
        }
        System.out.println("사용자 이름: " + name);
    }

    public static void main(String[] args) {
        try {
            validateUsername("");  // 예외 발생
        } catch (InvalidUserException e) {
            System.out.println("예외 처리됨: " + e.getMessage());
        }
    }
}
728x90
반응형