Exception Handling

박시시·2022년 9월 27일
0

JAVA

목록 보기
2/13

예외란?

오라클 공식문서에 따르면 아래와 같다.

An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program's instructions.

즉 예외란 프로그램 실행 중에 발생하는, 프로그램 명령의 정상적인 흐름을 방해하는 이벤트 이다.

메서드 내에서 에러가 발생하면 메서드는 exception object라는 객체를 만들어 런타임 시스템에 전달한다. 이 객체에는 에러 타입, 에러가 발생했을 시의 프로그램 상태 등의 정보를 담고 있다. 이렇게 런타임 시스템에 전달하는 작업을 'throwing an exception' 즉 예외를 던진다고 표현한다.

메서드가 이렇게 예외를 던지면 런타임 시스템은 이를 처리할 무언가를 찾고자 한다. 즉 메서드 콜스택 내에서 해당 예외를 처리할 수 있는 메서드를 찾는다.

(출처: 오라클공식문서)

이렇게 예외 처리를 할 수 있는 메서드의 코드 블록을 'exception handler'라 부른다.
이 exception handler는 예외를 catch한다고 하는데, 런타임 시스템이 적절한 핸들러를 찾지 못한다면 런타임시스템(결과적으론 프로그램)이 종료된다.

(출처: 오라클공식문서)

Checked Exception과 Unchecked Exception

(출처: https://voyager.deanza.edu/~hso/cis35a/lecture/java13/intro/hier.html)

에러와 관련된 클래스 계층구조는 위와 같다. Exception을 직접 상속받은 클래스를 checked exception이라 하며 그 외에는 unchecked exception이다.

Checked exception

이러한 예외는 '잘 작성된 애플리케이션'이 예상할 수 있고, 또 복구해야 하는 예외이다.
예를 들어 사용자에게 파일 이름을 입력하게 하여 해당 파일을 여는 애플리케이션이 있다고 하자. 보통은 읽을 수 있는 파일 이름을 전달할 것이다. 하지만 실수로 존재하지 않는 파일 이름을 입력하게 되면 FileNotFoundException 예외를 던지게 된다. 잘 작성된 애플리케이션은 이러한 예외를 캐치하고 유저가 실수했다는 사실을 알리며 다시 수정해서 입력하라는 메시지를 보낸다.

즉 클라이언트(혹은 메서드 호출자)가 예외로부터 복구될 수 있을거라고 합리적으로 예상할 수 있을 때 checked exception을 사용한다.

checked exception은 반드시 try-catch로 감싸거나 throws를 하든지 해서 반드시 에러를 처리해야 한다. 그렇지 않으면 컴파일시 에러가 발생하게 된다.

Unchecked exception

runtime exception 이라고도 한다. 애플리케이션이 예상하거나 복구할 수 없는, 애플리케이션 내부에서 발생하는 예외 이다. 보통은 로직 에러나 부적절한 API 사용과 같은 프로그래밍적인 버그이다. 예를 들어 위의 예에서 로직에러가 발생하여 null값이 넘어갔을 때 메서드는 NullPointerException 예외를 던지게 된다. 애플리케이션이 이 예외를 캐치할 수도 있지만, 그렇다고 클라이언트 혹은 메서드 호출자가 이 예외로부터 복구하기 위해 어떤 조치를 취할 수 있는것도 아니다. 그러니 해당 버그를 제거하는 방향이 좀 더 합리적일 수 있다.

즉 클라이언트(혹은 메서드 호출자)가 예외로부터 복구되기 위해 할 수 있는 것이 아무것도 없을 때, unchecked exception을 사용한다

checked exception과 달리 try-catch로 감싸거나 throws를 안한다고 컴파일 에러가 발생하지 않는다.

Error

애플리케이션이 예상하거나 복구할 수 없는, 애플리케이션 외부에서 발생하는 예외이다.
라이브러리 비호환이나 무한 재귀, 메모리 누수 같은 심각하고 일반적으로 복구할 수 없는 상태를 나타낸다. RuntimeException을 상속받지 않았지만 unchecked이다. 즉 컴파일 시가 아닌 런타임에 발생한다. 이러한 에러는 캐치하는 것보다 스택 트레이스를 인쇄하고 종료되는 것이 보통은 더 합리적인 처리이다.
역시나 try-catch로 감싸거나 throws를 안한다고 컴파일 에러가 발생하지 않는다.

0개의 댓글