목차
예외처리(exception handling)
예외처리란 프로그램 실행 시 발생할 수 있는 예기치 못한 예외의 발생에 대비한 코드를 작성하는 것이다. 예외의 발생으로 인한 실행중인 프로그램의 갑작스러운 비정상 종료를 막고, 정상적인 실행 상태를 유지할 수 있도록 하는 것이다.
예외의 종류
컴파일 에러와 런타임 에러
프로그램이 실행 중 오작동을 하거나 비정상적으로 종료되는 것을 프로그램 에러 또는 오류라고 한다. 이는 발생 시점에 따라 컴파일 에러(compile-time error) 와 런타임 에러(runtime error) 로 나눌 수 있다.
컴파일 에러 - 컴파일 시에 발생하는 에러
런타임 에러 - 실행 시에 발생하는 에러
논리적 에러 - 실행은 되지만, 의도와 다르게 동작하는 것
소스코드를 컴파일 하면 컴파일러가 소스코드에 대해 오타나 잘못된 구문, 자료형 체크 등의 기본적인 검사를 수행하여 오류가 있는지를 알려 준다. 오류가 있다면 컴파일 에러가 발생하게 된다.
컴파일러가 알려 준 에러들을 모두 수정해서 컴파일을 성공적으로 마치고 나면, 클래스 파일(*.class)이 생성되고, 생성된 클래스 파일을 실행할 수 있게 된다.
Exception 클래스
모든 예외의 최고 조상은 Exception 클래스이다. 위 그림에서 볼 수 있듯이 예외 클래스들은 다음과 같이 두 개의 그룹으로 나눠질 수 있다.
- RuntimeException 클래스와 그 자손 클래스들(그림의 아랫부분)
- 주로 프로그래밍 실수에 의해서 발생
- Exception 클래스와 그 자손 클래스들 (RuntimeException 을 제외한 그림의 윗부분)
- 존재하지 않는 파일의 이름을 입력하거나, 클래스 이름을 잘못적는 등 주로 외부 영향으로 발생.
예외 처리하기( try-catch문 )
예외를 처리하기 위해서는 다음과 같이 try-catch문을 사용해야 한다.
try{
// 예외가 발생할 가능성이 있는 문장들을 넣는다.
}catch(Exception e){
//해당 예외가 발생했을 경우 이를 처리하기 위한 문장을 적는다.
}finally{
//예외의 발생여부에 상관없이 무조건 수행된다.
}
예외가 발생할 가능성이 있는 문장을 try 블럭에 넣는다.
그 후 예외가 발생하면 어떻게 처리할지를 catch 블럭에 넣는다.
마지막으로 예외의 발생 여부에 상관없이 실행되어야할 코드를 finally블럭에 넣는다. finally 블럭은 있어도 되고 없어도 된다.
try-catch문의 흐름
- try블럭 내에서 예외가 발생한 경우
- 발생한 예외와 일치하는 catch 블럭이 있는지 확인한다.
- 일치하는 catch블럭을 찾으면 그 catch블럭 내의 문장들을 수행하고, 일치하는 catch블럭을 찾지 못하면 예외는 처리되지 못한다.
- try블럭 내에서 예외가 발생하지 않은 경우
- catch블럭을 거치지 않고 전체 try-catch문을 빠져나가서 수행을 계속한다.
public static void main(String[] args) {
System.out.println("ㄱ"); //----- 1
try{
System.out.println("ㄴ"); //----- 2
System.out.println(0/0); // 0으로 나누어서 고의로 Exception 발생
System.out.println("ㄷ"); //----- 3
}catch(Exception e){
System.out.println("ㄹ"); //----- 4
}finally{
System.out.println("ㅁ"); //----- 5
}
}
Exception이 발생했을 경우
1번 실행 -> 2번 실행 -> Exception 발생! -> 3번 실행하지않고 4번 실행 -> 5번 실행
catch 블럭
예외가 발생했을 때 생성되는 예외 클래스의 인스턴스에는 발생한 예외에 대한 정보가 담겨져 있다. 때문에 getMessage()와 printStackTrace()를 통해서 어떤 예외가 발생되었는지 알 수 있다. catch 블럭의 괄호 안에 선언된 참조변수를 통해 접근해 사용할 수 있다.
public static void main(String[] args) {
try{
System.out.println(0/0); // 0으로 나누어서 고의로 Exception 발생
}catch(Exception e){
e.getMessage(); // 발생한 예외클래스의 인스턴스에 저장된 메세지를 얻을 수 있다.
e.printStackTrace(); // 호출스택에 있었던 메서드의 정보와 메세지를 화면에 출력한다.
//다음과 같이 출력해 콘솔창에서 확인할 수 있다.
System.out.println(e.getMessage());
}
}
고의로 예외 발생시키기
키워드 throw 를 사용해서 프로그래머가 고의로 예외를 발생시킬 수 있으며 방법은 아래의 순서를 따른다.
1. 연산자 new 를 이용해 발생시키려는 예외 클래스의 객체를 만든다.
Exception e = new Exception("고의로 발생")
2. 키워드 throw를 이용해서 예외를 발생시킨다.
throw e;
예시는 다음과 같다.
public static void main(String[] args) {
try{
Exception e = new Exception("고의로 발생시킴");
throw e;
}catch(Exception e){
e.printStackTrace();
System.out.println("에러메세지 : " + e.getMessage());
}
}
결과
사용자정의 예외 만들기
필요에 따라 프로그래머가 새로운 예외 클래스를 정의하여 사용할 수 있다.
public class MyException extends Exception{ // Exception 클래스를 상속받는다.
//에러 코드 값을 저장하기 위한 필드
private final int ERR_CODE; // 생성자를 통해 초기화할 것
MyException(String msg, int errCode){ // 문자열을 매개변수로 받는 생성자
super(msg); // 조상인 Exception클래스의 생성자를 호출한다.
ERR_CODE = errCode;
}
MyException(String msg){ // 생성자
this(msg, 100); //에러코드를 따로 입력하지 않을 경우 100으로 초기화
}
public int getErrorCode(){ // 에러 코드를 얻을 수 있는 메서드
return ERR_CODE;
}
}
참고
자바의 정석 남궁성