예외 처리

이용만·2023년 3월 6일
0
post-thumbnail

예외처리란 예기치 않게 발생하는 에러에 대응할 수 있는 코드를 미리 사전에 작성하여
프로그램의 비정상적인 종료를 방지하고, 정상적인 실행 상태를 유지하기 위한
자바의 "예외 처리" 이다.

컴파일 에러

런타임 에러

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
	at ErrorTest.main(ErrorTest.java:4)

에러와 예외

프로그램 오류에서는 크게 에러와 예외로 나뉜다.

에러는 복구하기 어려운 수준의 심각한 오류를 의미하고 대표적으로 메모리 부족과 스택 오버플로우가 있다.

반면 예외는 잘못된 사용 또는 코딩으로 인한 상대적으로 미약한 수준의 오류로서 코드 수정 등을 통해 수습이 가능한 오류를 이야기 한다.

우린 주로 개발자에 의해 핸들링이 가능한 예외(Exception)을 학습 한다.

🔎예외 클래스의 상속 계층도

모든 예외의 최고 상위 클래스인 Exception 클래스는 크게 일반 예외 클래스, 실행에외 클래스로 나뉜다.

일반 예외 클래스(Exception)
잘못된 클래스명(ClassNotFoundException)이나 데이터 형식(DataFormatException) 등 사용자편의 실수로 발생하는 경우가 많다.

실행 예외 클래스(Runtime Exception)
런타임 시 발생하는 RuntimeException 클래스와 그 하위클래스를 지칭한다.
주로 개발자의 실수에 의해 발생하는 경우이다.
클래스 간 형변환 오류(ClassCastException), 벗어난 배열 범위 지정(ArrayIndexOutOfBoundsException), 값이 null인 참조변수 사용(NullPointerException) 등이 있다.

🔎try - catch문

try{
            //예외가 발생할 가능성이 있는 코드를 삽입
        }
        catch (ExceptionType1 e1){
            // ExceptionType1 유형의 예외 발생시 실행할 코드
        }
        catch (ExceptionType2 e2){
            //ExceptionType2 유형의 예외 발생 시 실행할 코드
        }
        finally {
            //있어도 그만 없어도 그만. 예외 발생 여부와 상관 없이 항상 실행
       }

try 블럭 안에 예외가 발생할 가능성이 있는 코드를 삽입한다.

예외 없이 정상적으로 실행되면 catch블럭은 실행되지 않고 finally 블럭이 실행된다.

finally 블럭은 필수가 아니다. 있어도 그만 없어도 그만. 만약 있을 경우 예외 발생 여부와 상관 없이 항상 실행 된다.

catch 블럭은예외가 발생하는 경우에 실행되는 코드이며, 여러 종류의 예외를 처리할 수 있다.
만약 catch 블럭이 여러개이면 일치하는 하나의 catch 블럭만이 실행 된다. 이후 예외처리 코드가 종료되거나 finally로 넘어간다.
또 만약 일치하는 블럭을 못찾으면 예외는 처리 못된다.


public class RuntimeExceptionTest {

    public static void main(String[] args) {
        System.out.println("[소문자 알파벳을 대문자로 출력하는 프로그램]");
        printMyName("abc"); // (1)
        printMyName(null); // (2) 넘겨주는 매개변수가 null인 경우 NullPointerException 발생
        System.out.println("[프로그램 종료]");
    }
    static void printMyName(String str) {
        String upperCaseAlphabet = str.toUpperCase();
        System.out.println(upperCaseAlphabet);
    }

}
//출력값
[소문자 알파벳을 대문자로 출력하는 프로그램]
ABC //(3) 정상 실행
Exception in thread "main" java.lang.NullPointerException // (4) 예외 발생!

try - catch 문을 사용해보자

public class RuntimeExceptionTest {

    public static void main(String[] args) {

        try {
            System.out.println("[소문자 알파벳을 대문자로 출력하는 프로그램]");
            printMyName(null); // (1) 예외 발생
            printMyName("abc"); // 이 코드는 실행되지 않고 catch 문으로 이동
        } 
        catch (ArithmeticException e) {
            System.out.println("ArithmeticException 발생!"); // (2) 첫 번째 catch문
        } 
        catch (NullPointerException e) { // (3) 두 번째 catch문
            System.out.println("NullPointerException 발생!"); 
            System.out.println("e.getMessage: " + e.getMessage()); // (4) 예외 정보를 얻는 방법 - 1
            System.out.println("e.toString: " + e.toString()); // (4) 예외 정보를 얻는 방법 - 2
            e.printStackTrace(); // (4) 예외 정보를 얻는 방법 - 3
        } 
        finally {
            System.out.println("[프로그램 종료]"); // (5) finally문
        }
    }

    static void printMyName(String str) {
        String upperCaseAlphabet = str.toUpperCase();
        System.out.println(upperCaseAlphabet);
    }
}


(1) 예외 발생
null 값을 매개변수로 넘긴 메서드가 에러 발생
printMyname("abc")는 호출 되지 않는다.
바로 catch문으로 이동.

(2) 첫번째 catch문
발생한 예외는 NullPointException이므로 ArithmeticException은 그냥 지나간다.
한가지 유의할 점은 예외가 발생하면 catch 블럭은 위에서부터 순차적으로 검사를 진행하기에
구체적인 하위클래스를 먼저 위에 배치한다.

(3) 두번째 catch문
발생한 예외와 일치하는 조건이기에 실행이 된다.
예외가 발생했을 때 생성되는 예외 객체로부터 해당 에러에 대한 정보를 얻는 방법이 있다.

예외 객체 대표 3가지의 차이점
e.getMessage()
e.toString()
e.printStackTrace()

finally문
예외 발생 여부 상관 없이 실행된다.


🔎예외 전가

void ExampleMethod() throws Exception {
}

예제코드
업로드중..

throws 키워드를 사용하여 해당 예외를 발생한 메서드 안에서 처리하지 않고
메서드를 호출한 곳으로 다시 떠넘기고 있다.
예외처리의 책임을 throwException메서드가 아닌 main 메서드가 지게 되었다.

예외를 의도적으로 발생시키기

throw 키워드를 사용하면 의도적으로 예외를 발생시킬 수 있다.
업로드중..

아직 이해 안가는 부분이 좀 많아 생활코딩을 보았다.

profile
성장하는 개발자가 되고자 합니다.

0개의 댓글