Language/JAVA

[이것이 자바다].ch10.예외처리

JSJH._. 2025. 12. 28. 15:37

[이것이 자바다] 10. 예외처리

안녕하세요. 이번에는 자바의 예외처리에 대해 정리한 내용입니다.
매번 중요하다 말은 하지만 이번엔 진짜 중요합니다. 솔직히 혼자 개발하거나 공부할때 이걸 많이 쓸 필요는 없습니다. 간단한 문제 과정에서는 예외도 우리가 예상할수 있는정도에서 발생하고 왠만하면 통제할수있기 마련입니다. 하지만 프로그램이 커지고 조금더 실무에 가까워지면 예외 처리는 필수적이고 반드시 사용되기때문에 그냥 습관처럼 익혀두는것이 좋습니다.


1. 예외(Exception)

  • 프로그램 실행 중에 발생하는 예상치 못한 문제 상황입니다.
    • 컴파일 에러(Compile Error)와 차이가 있습니다.
    • 예외는 일단 프로그램이 정상적으로 실행되다가 문제가 발생하여 프로그램의 흐름을 방해합니다.

예시

  • NullPointerException: null 값을 가진 참조 변수의 멤버에 접근하려 할 때 발생합니다.
  • ArrayIndexOutOfBoundsException: 배열의 범위를 벗어난 인덱스에 접근하려 할 때 발생합니다.
  • NumberFormatException: 숫자로 변환할 수 없는 문자열을 숫자로 바꾸려 할 때 발생합니다.

예외가 발생하면, 프로그램은 그 자리에서 즉시 실행을 멈추고 비정상적으로 종료됩니다.

  • 예외 처리(Exception Handling): 예외가 발생하더라도 프로그램이 멈추지 않고, 미리 준비해둔 대응 코드를 실행하여 정상적인 흐름으로 복귀시키거나, 사용자에게 무슨 일이 일어났는지 알려주고 안전하게 종료하는 것입니다.

2. 예외의 종류

자바의 모든 예외와 에러는 Throwable 클래스를 상속받으며, 크게 세 가지로 나뉩니다.

  • 에러 (Error)
    • 시스템 레벨에서 발생하는 심각한 문제입니다.
    • 코드 레벨에서 수습할 수 없는 상황을 의미합니다. (예: 메모리 부족, 스택 오버플로우)
  • 예외 (Exception)
    • 코드 레벨에서 수습할 수 있는 문제 상황입니다.
    • 일반 예외 (General Exception / Checked Exception)
      • RuntimeException을 상속하지 않는 모든 예외입니다.
      • 컴파일러가 예외 처리 여부를 반드시 확인(Check)하는 예외입니다. (처리하지 않으면 컴파일 안됨)
    • 실행 예외 (Runtime Exception / Unchecked Exception)
      • RuntimeException을 상속하는 예외입니다.
      • 컴파일러가 예외 처리 여부를 확인하지 않는(Uncheck) 예외입니다.
      • 개발자의 부주의나 잘못된 코딩 습관으로 인해 발생하는 경우가 많습니다.

3. 예외 처리의 핵심: try-catch-finally

try-catch 블록

  • try 블록: 예외 발생 가능성이 있는 위험한 코드를 감싸는 영역입니다.
  • catch 블록: try 블록 안에서 특정 예외가 발생했을 때, 그것을 붙잡아 처리하는 코드 영역입니다.
  • 동작 원리
    1. try 블록의 코드 실행
    2. 예외가 발생하지 않으면, catch 블록은 완전히 무시
    3. 예외가 발생하면, 그 즉시 try 블록의 실행을 멈추고, 발생한 예외 객체와 일치하는 타입을 가진 catch 블록으로 이동 코드 실행
try {
    // 예외 발생 가능성이 있는 코드
    String data = "백";
    int value = Integer.parseInt(data); // NumberFormatException 발생!
} catch (NumberFormatException e) {
    // 예외를 잡아서 처리하는 코드
    System.out.println("숫자로 변환할 수 없는 값입니다.");
    // 예외 정보를 확인하는 유용한 메소드들
    System.out.println("예외 정보: " + e.getMessage()); //
    e.printStackTrace(); // 예외 발생 경로를 추적하여 모두 출력 (개발 시 필수)
}

다중 catch 블록

  • 여러 개의 catch 블록을 사용하여 각각의 예외를 따로 처리 가능합니다.
  • | 기호를 사용해 여러 예외를 하나의 catch 블록에서 동시에 처리 가능합니다.
try {
    // ...
} catch (ArrayIndexOutOfBoundsException e) { //
    // 배열 관련 예외 처리
} catch (NumberFormatException e) { //
    // 숫자 변환 관련 예외 처리
} catch (Exception e) {
    // 위에서 잡지 못한 나머지 모든 예외를 처리 (항상 마지막에 위치해야 함)
}

finally 블록

  • try 블록에서 예외가 발생하든, 발생하지 않든 상관없이 무조건, 반드시 실행되는 코드 영역입니다.
  • 사용 목적: 프로그램 실행 중 사용했던 자원(Resource)을 안전하게 해제하기 위해 사용합니다. (예: 파일 닫기, 네트워크 연결 끊기 등)
  • 자동 리소스 닫기 (try-with-resources)
    • AutoCloseable 인터페이스를 구현한 리소스 객체를 try() 괄호 안에 선언하면 finally 블록 없이 자동 리소스 닫기 가능합니다.

4. 예외 떠넘기기: throws

  • 현재 메소드에서 발생한 예외를 try-catch 처리하지 않고, 이 메소드를 호출한 쪽으로 책임을 떠넘기는 것입니다.
  • 사용법: 메소드 선언부 끝에 throws 예외클래스, ... 작성합니다.
// findClass 메소드는 예외를 직접 처리하지 않고, 호출한 쪽으로 떠넘긴다.
public void findClass() throws ClassNotFoundException { //
    Class.forName("java.lang.String2");
}

5. 사용자 정의 예외와 예외 발생시키기

  • 사용자 정의 예외
    • 자바에서 제공하는 예외 외에, 개발자가 특정 로직에 맞는 예외 직접 생성하는 것입니다.
    • Exception (일반 예외) 또는 RuntimeException (실행 예외) 클래스 상속받아 새로운 예외 클래스 생성합니다.
  • 예외 발생시키기 throw new 예외객체();
    • 개발자가 코드 내에서 의도적으로 예외 발생시킬 때 사용합니다.

감사합니다.