JAVA/자바 기초

[JAVA]예외처리(exception handling)-종류,예외처리방법,사용자정의예외

다당근 2021. 10. 18. 18:33

 

목차

     

     

     

    예외처리(exception handling)

    예외처리란 프로그램 실행 시 발생할 수 있는 예기치 못한 예외의 발생에 대비한 코드를 작성하는 것이다. 예외의 발생으로 인한 실행중인 프로그램의 갑작스러운 비정상 종료를 막고, 정상적인 실행 상태를 유지할 수 있도록 하는 것이다.

     

    예외의 종류

     

    컴파일 에러와 런타임 에러

    프로그램이 실행 중 오작동을 하거나 비정상적으로 종료되는 것을 프로그램 에러 또는 오류라고 한다. 이는 발생 시점에 따라 컴파일 에러(compile-time error)런타임 에러(runtime error) 로 나눌 수 있다.

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

    소스코드를 컴파일 하면 컴파일러가 소스코드에 대해 오타나 잘못된 구문, 자료형 체크 등의 기본적인 검사를 수행하여 오류가 있는지를 알려 준다. 오류가 있다면 컴파일 에러가 발생하게 된다.

    컴파일러가 알려 준 에러들을 모두 수정해서 컴파일을 성공적으로 마치고 나면, 클래스 파일(*.class)이 생성되고, 생성된 클래스 파일을 실행할 수 있게 된다.

     

    Exception 클래스

    모든 예외의 최고 조상은 Exception 클래스이다. 위 그림에서 볼 수 있듯이 예외 클래스들은 다음과 같이 두 개의 그룹으로 나눠질 수 있다.

    1. RuntimeException 클래스와 그 자손 클래스들(그림의 아랫부분)
      • 주로 프로그래밍 실수에 의해서 발생
    2. Exception 클래스와 그 자손 클래스들 (RuntimeException 을 제외한 그림의 윗부분)
      • 존재하지 않는 파일의 이름을 입력하거나, 클래스 이름을 잘못적는 등 주로 외부 영향으로 발생.

     

    예외 처리하기( try-catch문 )

    예외를 처리하기 위해서는 다음과 같이 try-catch문을 사용해야 한다.

     

     try{
            // 예외가 발생할 가능성이 있는 문장들을 넣는다.
        }catch(Exception e){
            //해당 예외가 발생했을 경우 이를 처리하기 위한 문장을 적는다.
        }finally{
            //예외의 발생여부에 상관없이 무조건 수행된다.
        }

    예외가 발생할 가능성이 있는 문장을 try 블럭에 넣는다.

    그 후 예외가 발생하면 어떻게 처리할지를 catch 블럭에 넣는다.

    마지막으로 예외의 발생 여부에 상관없이 실행되어야할 코드를 finally블럭에 넣는다. finally 블럭은 있어도 되고 없어도 된다.

     

    try-catch문의 흐름

    1. try블럭 내에서 예외가 발생한 경우
      1. 발생한 예외와 일치하는 catch 블럭이 있는지 확인한다.
      2. 일치하는 catch블럭을 찾으면 그 catch블럭 내의 문장들을 수행하고, 일치하는 catch블럭을 찾지 못하면 예외는 처리되지 못한다.
    2. try블럭 내에서 예외가 발생하지 않은 경우
      1. 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;
        }
    }

     

     


    참고

    자바의 정석 남궁성