본문 바로가기

JAVA의 정석

예외 처리(1) - 정의와 구조

1. 프로그램 오류

 

에러는 발생시점에 따라 컴파일 에러, 런타임 에러, 논리적 에러로 나눌 수 있다. 

 

컴파일에러는 컴파일시에 발생하는 에러 , 런타임 에러는 실행 시 발생하는 에러, 논리적 에러는 실행은 되지만 의도와 다르게 동작하는

 

에러를 뜻한다. 소스코드를 컴파일하면 컴파일러가 소스코드(*.java)에 대해 오타나 잘못된 구문, 자료형 체크 등의 기본적인 검사를

 

수행하여 성공적으로 마치고 나면, 클래스 파일(*.class)이 생성되고 , 생성된 클래스 파일을 실행할 수 있다.

 

하지만 컴파일을 에러 없이 성공적으로 마쳤다고 해서 프로그램 실행 시에도 에러가 발생하지 않는 것은 아니다. 컴파일러가 실행 도중

 

발생할 수 있는 잠재적인 오류까지 검사할 수 없기 때문에 컴파일은 잘 되었어도 실행 중에 에러에 의해서 잘못된 결과를 얻거나

 

프로그램이 비정상적으로 종료될 수 있다. 

 

런타임 에러를 방지하기 위해서는 프로그램의 실행 도중 발생할 수 있는 모든 경우의 수를 고려하여 이에 대한 대비를 하는 것이 필요하다.

 

자바에서는 실행 시 발생할 수 있는 프로그램 오류를 '에러(errorr)' 와 '예외(exception)' 두 가지로 구분하였다.

 

에러는 메모리 부족(OutofMemoryErrorr)나 스택오버플로우(StackOverflowError)와 같이 일단 발생하면 복구할 수 없는

 

심각한 오류이고, 예외는 발생하더라도 수습될 수 있는 비교적 덜 심각한 것이다.

 

 

2. 예외 클래스의 계층 구조

 

 

 

자바에서는 실행 시 발생할 수 있는 오류(Exception과 Error)를 클래스로 정의하였다. 앞서 배운 것처럼 모든 클래스의 조상은 

 

Object 클래스이므로 Exception 과 Error클래스 역시 Object클래스의 자손들이다. 

 

모든 예외의 최고 조상은 Exception 클래스이며, 상속계층도를 Exception 클래스로부터 도식화하면 다음과 같다.

 

Exception 클래스와 RuntimeException 클래스 중심의 상속계층도

 

위 그림에서 볼 수 있듯이 예외 클래스들은 다음과 같이 두 그룹으로 나누어진다.

 

(1) Exception 클래스와 그 자손들 (RuntimeException과 자손들 제외)

 

(2) RuntimeException 클래스와 그 자손들

 

 

3. Exception과 RuntimeException

 

Excption 클래스들 : 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외
RuntimeException 클래스들 : 프로그래머의 실수로 발생하는 예외

 

 

Exception 클래스들은 주로 외부의 외부의 영향으로 발생할 수 있는 것들로써, 프로그램의 사용자들의 동작에 의해서 발생하는 

 

경우가 많다. 예를 들면, 존재하지 않는 파일의 이름을 입력했다던가 (FileNotFoundException) , 실수로 클래스의 이름을 잘못

 

적었다던가(ClassNotFoundException) , 또는 입력한 데이터 형식이 잘못된(DataFormatException) 경우에 발생한다.

 

 

RuntimeException 클래스들은 주로 프로그래머의 실수에 의해서 발생될 수 있는 예외들로 자바의 프로그래밍 요소들과 관계가

 

깊다. 예를 들면, 배열의 범위를 벗어난다던가(ArrayIndexOutOfBoundsException), 값이 null인 참조변수의 멤버를 호출하려 

 

했다던가(NullPoinerException), 클래스간의 형변환을 잘못했다던가(ClassCastException),

 

정수를 0으로 나누려고(ArithmeticException) 하는 경우에 발생한다.

 

 

4. 예외 처리하기 - try - catch 문

 

 

프로그램의 실행도중에 발생하는 에러는 어쩔 수 없지만, 예외는 프로그래머가 이에 대한 처리를 미리 해주어야 한다.

 

예외처리(exception handling)란, 프로그램 실행 시 발생할 수 있는 예기치 못한 예외의 발생에 대비한 코드를 작성하는 것이며,

 

예외처리 목적은 예외의 발생으로 인한 실행 중인 프로그램의 갑작스런 비정상 종료를 막고, 정상적인 실행 상태를 유지할 수

 

있도록 하는 것이다.

 

예외처리(exception handling)의 

     정의  프로그램 실행 시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것
     목적  프로그램의 비정상 종료를 막고, 정상적인 실행상태를 유지하는 것

 

 

발생한 예외를 처리하지 못하면, 프로그램은 비정상적으로 종료되며, 처리하지 못한 예외(uncaught exception)은

 

JVM의 '예외처리기(UncaughtExceptionHandler)'가 받아서 예외의 원인을 화면에 출력한다.

 

예외를 처리하기 위해서는 try - catch 문을 사용하며,  구조는 다음과 같다.

 

try{
    // 예외가 발생할 수 있는 문장들을 넣는다.
} catch (Exception1 e1) {
    // Exception1이 발생했을 경우, 이를 처리하기 위한 문장을 넣는다.
} catch (Exception2 e2) {
    // Exception1이 발생했을 경우, 이를 처리하기 위한 문장을 넣는다.
} catch (ExceptionN eN) {
    // Exception1이 발생했을 경우, 이를 처리하기 위한 문장을 넣는다.
}

 

 

하나의 try 블럭 다음에는 여러 종류의 예외를 처리할 수 있도록 하나 이상의 catch 블럭이 올 수 있으며, 이 중 발생한 예외의 종류와 

 

일치하는 단 한 개의 catch블럭만 수행된다. 발생한 예외의 종류와 일치하는 catch 블럭이 없으면 예외는 처리되지 않는다. 

 

여기서 if문과 달리, try 블럭이나 catch 블럭 내에 포함된 문장이 하나 뿐이어도 중괄호{}를 생략할 수 없다.