프로그램이 실행 중 어떤 원인에 의해서 오작동하거나 비정상적으로 종료되는 경우, 이때의 원인을 프로그램 에러 또는 오류라고 하는데,
이를 발생시점에 따라 '컴파일 에러(compile-time error)'와 '런타임 에러(runtime error)'로 나눌 수 있다.
이 외에도 실행은 되지만, 의도와 다르게 동작하는 '논리적 에러'도 존재한다.
소스코드를 컴파일 하면 컴파일러가 소스코드에 대해 오타나 잘못된 구문, 자료형 체크 등의 기본적인 검사를 수행하여 오류가 있는지 알려준다. 컴파일러가 알려 준 에러들을 모두 수중해서 컴파일을 성공적으로 마치고 나면, 클래스 파일이 생성되고 생성된 클래스 파일을 실행할 수 있다.
하지만 컴파일은 잘 되었어도 실행 중에 에러에 의해서 잘못된 결과를 얻거나 프로그램이 비정상적으로 종료될 수 있다.
런타임 에러를 방지하기 위해서는 프로그램의 실행 도중 발생할 수 있는 모든 경우의 수를 고려하여 이에 대한 대비를 하는 것이 필요하다. 자바에서는 실행 시(runtime) 발생할 수 있는 프로그램 오류를 '에러(error)'와 '예외(exception)'로 구분하였다.
에러 (error) : 프로그램 코드에 의해서 수습될 수 없는 심각한 오류
예외(exception) 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류
모든 클래스의 조상은 Object클래스이며, Exception과 Error 클래스 역시 Object클래스의 자손들이다.


위 그림처럼 예외 클래스들은 두 그룹으로 나눌 수 있다.
1. Exception클래스와 자손들(RuntimeException과 자손들 제외)
2. RuntimeException 클래스와 그 자손들
1번 예외는 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외이고,
2번 예외는 프로그래머의 실스로 발생하는 예외이다.
프로그램의 실행 도중에 발생하는 에러는 어쩔 수 없지만, 예외는 프로그래머가 이에 대한 처리를 미리 해주어야한다.
예외처리(exception handling)는 프로그램 실행 시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것으로, 프로그램의 비정상적 종료를 막고, 정상적인 실행상태를 유지하기 위함이다.
발생한 예외를 처리하지 못하면, 프로그램은 비정상적으로 종료되며, 처리되지 못한 예외(uncaught exception)는 JVM의 '예외처리기(UncaughtExceptionHandler)'가 받아서 예외의 원인을 화면에 출력한다.
예외처리는 try-catch문을 사용하며,구조는 아래와 같다.
try {
// 예외가 발생할 가능성이 있는 부분
} catch (Exception1 e1) {
// Exception1이 발생했을 경우, 이를 처리하기 위한 문장
} catch (Exception2 e2) {
// Exception2이 발생했을 경우, 이를 처리하기 위한 문장
} catch (ExceptionN eN) {
// ExceptionN이 발생했을 경우, 이를 처리하기 위한 문장
}
하나의 try블럭 다음에는 여러 종류의 예외를 처리할 수 있도록 하나 이상의 catch 블럭이 올 수 있으며, 이 중 발생한 예외의 종류와 일치하는 단 한 개의 catch 블럭만 수행된다. 발생한 예외의 종류와 일치하는 catch블럭이 없으면 예외는 처리되지 않는다.
try블럭 내에서 예외가 발생하지 않는 경우에는 catch블럭을 거치지 않고 전체 try-catch문을 빠져나가서 수행을 계속한다.
try {
} catch
void method() throws Exception1, Exception2, ..., ExceptionN {
// 메서드 내용
}
메서드의 선언부에 예외를 선언함으로써 메서드를 사용하려는 사람이 메서드의 선언부를 보았을 때, 이 메서드를 사용하기 위해서는 어떠한 예외들이 처리되어져야 하는지 쉽게 알 수 있다.
이는 예외의 발생여부에 상관없이 실행되어야할 코드를 포함시킬 목적으로 사용된다.
try-catch-finally 순서로 구성된다.
try {
// 예외가 발생할 가능성이 있는 문장들
} catch (Exception e) {
// 예외처리를 위한 문장
} finally {
// 예외 발생여부에 관계없이 항상 수행되어야 하는 문장
}
예외가 발생한 경우에는 try → catch → finally 순으로 실행되고, 예외가 발생하지 않은 경우에는 try → finally 순으로 실행된다.
기존의 정의된 예외 클래스 외에 필요에 따라 새로운 예외 클래스를 정의하여 사용할 수 있다.
class MyException extends Exception {
MyException(String msg) { // 문자열을 매개변수로 받는 생성자
super(msg); // 조상인 Exception 클래스의 생성자를 호출한다.
}
}
출처
「Java의 정석」