[JAVA] 예외와 예외 처리(Exception handling)

2022. 9. 13. 20:48

프로그램 오류

프로그램 오류는 크게 2가지로 나뉜다.

1. 컴파일 에러: 컴파일할 때 발생하는 에러

public class ExceptionTest {
    public static void main(String[] args) {
        system.out.println("Compile error");
    }
}

대체로 문법상의 오류로 컴파일 자체가 되지 않는다. 이 경우는 보통 IDE에서 알려주기 때문에 상대적으로 발견하기 쉽고 어렵지 않게 해결할 수 있다.

 

2. 런타임 에러: 실행할 때 발생하는 에러

public class ExceptionTest {
    public static void main(String[] args) {
        System.out.println(args[0]);
    }
}

컴파일 에러와 다르게 IDE에선 확인할 수 없고 실행하면 java.lang.ArrayIndexOutOfBoundsException이 발생한다.

 


실행 시 발생하는 프로그램의 오류를 에러(error), 예외(exception) 2가지로 구분한다.

에러(error): 한 번 발생하면 복구하기 힘든 오류 ex) OutOfMemoryError, StackOverFlowError

예외(exception): 발생하더라도 상대적으로 수습될 수 있는 덜 심각한 오류

예외는 위 그림과 같이 Exception 클래스의 자손들과 RuntimeException 클래스의 자손들로 나누어진다.

 

RuntimeException과 하위 클래스들은 프로그래머의 실수에 의해서 발생될 수 있는 예외들이다. (ArrayIndexOutOfBoundsException, NullPointerException, ...)

 

RuntimeException을 제외한 Exception과 하위 클래스들은 주로 외부의 영향으로 발생할 수 있는 예외들이다. (FileNotFoundException, ClassNotFoundException, ...)


예외 처리

1. try - catch문

예외 처리란 잠재적으로 발생할 수 있는 비정상 종료나 오류에 대비하여 정상 실행을 유지할 수 있도록 하는 것이다.

이런 예외 처리를 try - catch 문으로 구현할 수 있다. 만약 처리하지 못한다면 JVM이 예외의 원인을 출력해준다.

 

예외 처리의 구조

try {
    // 예외 발생 가능성 있는 코드
} catch (ExceptionType1 e1){
    // ExceptionType1 예외 발생시 실행
} catch (ExceptionType2 e2){
    // ExceptionType2 예외 발생시 실행
} finally { //Optional
    //예외 여부와 상관없이 항상 실행
}

try: 예외가 발생할만한 코드가 들어가는 블록

catch: 예외가 발생하는 경우 실행되는 블록. 여러 개가 명시될 수 있고 일치하는 예외의 타입을 찾아서 수행 이때 해당 타입의 하위 클래스도 포함된다. 일치하는 블록이 없으면 예외가 출력되고 종료. 

finally: 예외 발생 여부와 상관없이 수행되는 코드

 

public class ExceptionTest {
    public static void main(String[] args) {
        try{
            System.out.println(10/2);
            System.out.println(0/0); // 1.예외 발생
            System.out.println(20/2); // 실행X
        } catch (ArithmeticException e){
            System.out.println("divide 0"); // 2.catch 블록 수행
        } finally {
            System.out.println("finally"); // 3.finally 블록 수행
        }
    }
}

출력

5
divide 0
finally

System.out.println(0/0); 라인에서 예외가 발생하면  다음 라인은 수행되지 않고 catch 블록으로 넘어가 예외가 처리되고 마지막으로 finally 블록이 수행된다.

2. throws

throws 키워드를 메서드 선언부에 발생할 수 있는 예외와 함께 적어준다.

반환타입 메서드명() throws Exception1, Exception2, ... { 
	//
}

try - catch는 예외가 발생하면 catch문으로 처리하지만 throws는 예외가 발생한 메서드에서 처리하지 않고 메서드를 호출한 곳에서 처리하도록 예외를 전달한다.

public class ExceptionTest {
    public static void main(String[] args){
        try {
            method();
        } catch (ClassNotFoundException e){
            System.out.println(e.getMessage());
        }
    }
    static void method() throws ClassNotFoundException {
        Class.forName("java.lang.string");
    }
}

method()에서 발생한 예외가 main으로 전달되어 main이 예외를 처리하게 된다.

 

throws를 사용하면 메서드 선언부를 보고 어떤 예외가 넘어올지 짐작할 수 있고 대처할 수 있게 된다.

 

 

 

 

BELATED ARTICLES

more