[Java] 예외처리

허경두·2025년 4월 3일

Java

목록 보기
7/12

예외처리란?

예외처리(Exception Handling) : 프로그램 실행 시 발생할 수 있는 예기치 못한 예외의 발생에 대비한 코드를 작성하는 것

목적 : 예외의 발생으로 인한 실행 중인 프로그램의 갑작스러운 비정상 종료를 막고, 정상적인 실행상태를 유지할 수 있도록 하는 것

프로그램 오류 : 프로그램 실행 중 오작동 하거나 비정상적으로 종료되는 경우의 원인

에러 종류발생 시점원인예시
컴파일 에러 (Compile-time Error)코드 작성 후 컴파일 시문법 오류, 타입 불일치, 선언되지 않은 변수 사용 등- 세미콜론(;) 누락
- 존재하지 않는 클래스나 메서드 호출
- 잘못된 타입 변환 (intString에 할당)
런타임 에러 (Runtime Error)프로그램 실행 중실행 중 예외 발생, 메모리 부족, 잘못된 연산- NullPointerException (null 객체 접근)
- ArrayIndexOutOfBoundsException (배열 범위 초과)
- ArithmeticException (0으로 나누기)
논리적 에러 (Logical Error)실행은 되지만 의도한 결과가 나오지 않음알고리즘 오류, 잘못된 조건문 사용- if (a = b) {} (비교 연산자 == 대신 = 사용)
- 반복문 조건 오류로 무한 루프 발생
- 올바른 값이 출력되지 않음

에러(error) : 코드로 처리할 수 없는 심각한 오류
예외(exception) : 코드로 처리할 수 있는 다소 미약한 오류

Java의 예외 클래스

  • Object (모든 클래스의 최상위 클래스)
    • Throwable (모든 예외 및 오류의 최상위 클래스)
      • Error (에러 - 프로그램이 복구할 수 없음)
        • OutOfMemoryError
        • StackOverflowError
        • VirtualMachineError
        • 기타 시스템 에러
      • Exception (예외 - 프로그램이 복구 가능)
        • RuntimeException (Unchecked 예외)
          • NullPointerException
          • ArrayIndexOutOfBoundsException
          • ArithmeticException
          • ClassCastException
          • 기타 실행 예외
        • IOException
          • FileNotFoundException
          • EOFException
          • 기타 입출력 예외
        • SQLException
        • InterruptedException
        • ParseException
        • 기타 일반 예외

* Exception 클래스의 RuntimeException을 제외한 예외는 Checked 예외이다

Checked Exception : 컴파일 타임 예외. 사용자의 실수와 같은 외적 요인에 의해 발생한다 (반드시 예외처리를 해야한다)
Unchecked Exception : 런타임 예외. 프로그래머의 실수로 발생한다

try-catch

try-catch 문을 사용해서 예외를 처리할 수 있다

try {
	// 예외가 발생할 가능성이 있는 문장들
} catch (Exception e) {
	// Exception이 발생했을 경우 처리할 문장들
} finally {
	// 예외 발생여부와 관계없이 수행되어야하는 문장들
}

사용한 자원을 반드시 반환해야 하는 경우, try-with-resources문으로 처리할 수 있다
괄호안에 객체를 생성하는 문장을 넣으면 try 블럭을 벗어나는 순간 close()가 자동으로 호출된다

try (FileInputStream fls = new FileInputStream("score.dat"); DataInputStream dis = new DataInputStream(fls)) {
	// 예외가 발생할 가능성이 있는 문장들
} catch (Exception e) {
	// Exception이 발생했을 경우 처리할 문장들
}

자원을 사용하고 반환해야 하는 경우 두 가지 경우를 생각해볼 수 있다
1. close() 에서 예외가 발생하는 경우
2. close()try 블럭 내에서 모두 예외가 발생하는 경우

  • try-catch 문을 사용할 경우
    1. finally 블럭에서 예외 처리 → 가능하지만 코드가 복잡해진다
    2. try 블럭의 예외는 무시된다
  • try-with-resources 문을 사용할 경우
    1. close() 에 대한 예외가 발생
    2. try 블럭 내에서 발생한 예외 내부에 close()에 대한 예외가 저장된다 → suppressed 로 저장된다

Throwable의 suppressed exception 관련 메서드

  • void addSuppressed(Throwable exception)
  • Throwable[] getSuppressed()

printStackTrace()와 getMessage()

Throwable에 구현된 printStackTrace()와 getMessage()를 사용해서 예외에 대한 정보를 출력하거나 얻을 수 있다

  • printStackTrace() : 예외발생 당시 Call Stack에 있었던 메서드의 정보와 예외 메세지를 화면에 출력
  • getMessage() : 발생한 예외클래스의 인스턴스에 저장된 메세지 반환

예외 발생시키기

throw 키워드를 사용해서 고의로 예외를 발생시킬 수 있다

예외 클래스의 객체를 생성한 다음 throw 객체명; 으로 사용한다

메서드에 예외 선언

해당 메서드에서 발생 가능성이 있는 예외들을 선언할 수 있다
선언한 예외가 발생할 가능성이 있으니 호출한 곳에서 처리하라는 뜻이다

void method() throws Exception1, Exception2, ... {
	...
}

사용자정의 예외

Exception class 나 RuntimeException class 로부터 상속받아 예외 클래스를 만들 수 있다 (필요에 따라 다른 예외클래스를 상속받아도 된다)

가능하면 기존의 예외클래스를 활용하는 것이 좋다

class MyException extends Exception {
	MyException(String msg) {
    	super(msg);
    }
}

예외 되던지기

catch 블럭에서 throw를 통해 예외를 되던질 수 있다

하나의 예외에 대해 예외가 발생한 메서드와 호출한 메서드 양쪽 모두 처리해야 할 작업이 있을 때 사용한다

연결된 예외

연결된 예외(chained exception) : 한 예외가 발생했을 때, 그 예외의 원인이 되는 또 다른 예외를 포함하여 처리하는 기법

Throwable의 suppressed exception 관련 메서드

  • Throwable initCause(Throwable cause) : 원인 예외로 등록
  • Throwable getCause() : 원인 예외 반환

연결된 예외를 사용하는 경우

  • 여러 예외를 하나의 큰 분류의 예외로 묶어서 다루려고 할 때
    → 연결된 예외를 사용하지 않으면 마지막에 발생한 예외 정보만 남는다
  • checked 예외를 unchecked 예외로 바꾸려고 할 때
    → Java 개발 초기 환경에 맞춰 구현된 checked 예외 처리의 강제성을 제거하기 위해

0개의 댓글