기록은 기억을 이기고 시간보다 오래 남는다.

프로그래밍 언어/JAVA

[JAVA]자바 예외 처리: 종류, 예제, 그리고 차이점

준_준 2025. 1. 9. 16:16

예외(Exception)란 무엇인가?

예외(Exception)는 프로그램 실행 중에 예기치 못한 상황으로 인해 발생하는 오류를 말합니다. 자바에서는 예외를 체계적으로 관리하고 처리하기 위해 다양한 예외 클래스와 메커니즘을 제공합니다. 예외 처리를 올바르게 하면 프로그램이 예기치 못한 상황에서도 정상적인 실행을 유지할 수 있습니다.


자바 예외의 종류

1. 논리적 에러 (Logic Errors)

  • 프로그램이 작동은 하지만, 결과가 의도와 다르게 나오는 경우입니다.
  • 디버깅 방법: 논리적 에러를 해결하려면 코드에서 문제가 되는 부분을 추적해야 합니다. 이를 위해 디버깅 도구를 사용하거나, 코드에 로그를 추가하여 실행 흐름과 변수 값을 확인하는 것이 유용합니다.
  • 컴퓨터 입장에서는 문제가 없어 에러 메시지가 나타나지 않지만, 사용자는 의도한 작업을 수행하지 못할 수 있습니다.
  • 예시:
    • 재고량이 음수로 나오는 경우
    • 게임 캐릭터의 체력이 0이어도 죽지 않는 경우

2. 컴파일 에러 (Compile Errors)

  • 코드가 문법적으로 올바르지 않아 컴파일이 되지 않는 오류입니다.
  • 프로그램이 실행조차 되지 않기 때문에 심각한 오류는 아니며, 수정 후 다시 컴파일하면 해결됩니다.
  • 대표적인 예시:
    • 문법 오류
    • 클래스 또는 메서드 이름을 잘못 작성

3. 런타임 에러 (Runtime Errors)

  • 프로그램 실행 중에 발생하는 오류입니다.
  • 잘못된 결과를 초래하거나 프로그램이 비정상적으로 종료될 수 있습니다.
  • 외부 요인(네트워크 문제, 파일 시스템 문제 등)으로 인해 발생하기도 합니다.

주요 예외 클래스

자바에서는 다양한 예외 상황을 처리하기 위해 예외 클래스가 제공됩니다. 주요 예외 클래스와 발생 상황은 아래와 같습니다:

1. ClassNotFoundException

  • 존재하지 않는 클래스를 사용하려고 했을 때 발생.

2. IOException

  • 파일 입출력 과정에서 문제가 발생했을 때 발생.

3. SQLException

  • 데이터베이스와 연동 중 문제가 발생했을 때 발생.

4. NumberFormatException

  • 숫자 형식이 아닌 데이터를 숫자로 변환하려고 했을 때 발생.

5. ClassCastException

  • 불가능한 타입 변환을 시도할 때 발생.

6. ArrayIndexOutOfBoundsException

  • 배열의 유효하지 않은 인덱스에 접근하려고 했을 때 발생.


예외 처리 구조

자바에서는 예외를 처리하기 위해 try-catch 블록을 사용합니다. 예외가 발생할 가능성이 있는 코드는 try 블록에 작성하고, 발생한 예외를 처리하는 코드는 catch 블록에 작성합니다.

예제 코드: ArithmeticException 처리

public class ExceptionExample {
    public static void main(String[] args) {
        int a, b, c;
        try {
            a = 10;
            b = 0;
            c = a / b; // 10 나누기 0 → 산술 오류 ArithmeticException 발생
        } catch (ArithmeticException e) {
            c = -1; // 예외가 발생하여 이 문장이 수행됩니다.
            System.out.println("0으로 나눌 수 없습니다: " + e.getMessage());
        }
    }
}

예제 코드: 다양한 예외 처리

public class MultiCatchExample {
    public static void main(String[] args) {
        try {
            String[] array = {"10", "20", null};
            int num = Integer.parseInt(array[1]);

            System.out.println("숫자: " + num);
        } catch (NumberFormatException e) {
            System.out.println("숫자로 변환할 수 없습니다.");
        } catch (NullPointerException e) {
            System.out.println("NULL 값을 참조했습니다.");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("배열 인덱스가 범위를 벗어났습니다.");
        } finally {
            System.out.println("예외와 상관없이 항상 실행됩니다.");
        }
    }
}

Checked Exception vs Unchecked Exception

1. Checked Exception

  • 컴파일 타임에 확인되는 예외로 반드시 예외 처리를 해야 합니다.
  • 처리하지 않으면 컴파일 오류가 발생합니다.
  • 예시:
    • IOException: 파일을 읽거나 쓸 때 문제가 발생하는 경우.
      • 사용 사례: 파일을 읽어들이는 프로그램에서, 해당 파일이 없을 경우 예외 처리.
    • SQLException: 데이터베이스 접근 시 문제가 발생하는 경우.
      • 사용 사례: 데이터베이스에서 데이터를 조회할 때 네트워크 연결 문제로 예외가 발생.

2. Unchecked Exception

  • 런타임에 확인되는 예외로 명시적으로 예외 처리를 하지 않아도 됩니다.
  • 대부분 프로그래머의 실수로 발생하므로 주의 깊게 코드를 작성하면 예방할 수 있습니다.
  • 예시:
    • NullPointerException: 객체가 null인 상태에서 메서드 호출 시 발생.
      • 사용 사례: 초기화되지 않은 객체를 참조하려고 할 때.
    • ArrayIndexOutOfBoundsException: 배열의 유효하지 않은 인덱스에 접근하려고 했을 때 발생.
      • 사용 사례: 배열의 크기를 초과하는 인덱스에 접근하려 할 때.

분류 이유

  • Checked Exception은 반드시 예외 처리가 필요하기 때문에 컴파일러 단계에서 강제합니다.
  • 반면, Unchecked Exception은 개발자가 코드를 주의 깊게 작성하면 충분히 회피할 수 있는 상황이므로 명시적인 예외 처리를 강제하지 않습니다.
  • 컴파일 타임에 확인되는 예외로 반드시 예외 처리를 해야 합니다.
  • 처리하지 않으면 컴파일 오류가 발생합니다.
  • 예시:
    • IOException
    • SQLException

2. Unchecked Exception

  • 런타임에 확인되는 예외로 명시적으로 예외 처리를 하지 않아도 됩니다.
  • 대부분 프로그래머의 실수로 발생하므로 주의 깊게 코드를 작성하면 예방할 수 있습니다.
  • 예시:
    • NullPointerException
    • ArrayIndexOutOfBoundsException

분류 이유

  • Checked Exception은 반드시 예외 처리가 필요하기 때문에 컴파일러 단계에서 강제합니다.
  • 반면, Unchecked Exception은 개발자가 코드를 주의 깊게 작성하면 충분히 회피할 수 있는 상황이므로 명시적인 예외 처리를 강제하지 않습니다.

예외 메시지 출력 방법

1. printStackTrace()

  • 예외 발생 당시의 호출 스택과 예외 메시지를 출력합니다.
  • 프로그램의 내부 동작을 자세히 보여주므로 디버깅에 유용하지만, 외부 노출 시 보안 문제가 발생할 수 있습니다.
  • 대안: SLF4J, Log4j, 또는 java.util.logging과 같은 로깅 프레임워크를 사용하여 예외 메시지를 기록하면, 보안성과 가독성을 모두 확보할 수 있습니다.

2. getMessage()

  • 예외 클래스의 인스턴스에 저장된 메시지를 반환합니다.

예제

public class ExceptionMessageExample {
    public static void main(String[] args) {
        try {
            int result = 10 / 0;
        } catch (ArithmeticException e) {
            e.printStackTrace();
            System.out.println("예외 메시지: " + e.getMessage());
        }
    }
}

요약

자바에서 예외 처리는 프로그램의 안정성과 사용자 경험을 향상시키기 위해 매우 중요합니다. 또한, finally 블록을 사용하여 자원 정리 작업을 수행하거나, 상황에 맞는 사용자 정의 예외를 만들어 예외 처리의 가독성과 효율성을 높일 수 있습니다. 다양한 예외 클래스와 예외 처리 메커니즘을 활용하여 예외 상황을 효과적으로 관리할 수 있습니다. 또한, Checked Exception과 Unchecked Exception의 차이를 이해하고 적절히 활용하면 효율적인 코드를 작성할 수 있습니다.

반응형