예외처리(Exception Handling)

김수민·2023년 3월 12일
0

백엔드 부트캠프

목록 보기
19/52
post-thumbnail

예외 처리란?

  • 예기치 않게 발생하는 에러에 대응할 수 있는 코드를 미리 사전에 작성해여 프로그램의 비정상적인 종료를 방지하고, 정상적인 상태를 유지하기 위함.
  • 프로그래밍에서 에러가 발생하는 이유
    - 외부적인 요인: 하드웨어의 문제, 네트워크의 연결 끊김, 사용자 조작 오류 등
    • 내부적인 요인: 개발자의 코드 작성 에러
  • 발생하는 시점에 따라 컴파일 에러(Compile Time Error)와 런타임 에러(Runtime Error)로 구분할 수 있음

컴파일 에러와 런타임 에러

컴파일 에러

  • 컴파일 에러: "컴파일 할 때" 발생하는 에러
  • 주로 세미콜론 생략, 오탈자, 잘못된 자료형, 잘못된 포맷 등 문법적인 문제를 가리키는 신택스(syntax) 오류로부터 발생하기 때문에 신택스 에러(Syntax Errors)라고 부르기도 함
  • 자바 컴파일러가 오류를 감지하여 사용자에게 친절하게 알려주기 때문에 상대적으로 쉽게 발견하고 수정할 수 있음

런타임 에러

런타임 시에 발생하는 에러. 개발자가 컴퓨터가 수행할 수 없는 특정한 작업을 요청할 대 발생.
컴파일 에러가 자바 컴파일러에 의해 발견되는 것이라면, 런타임 에러는 프로그램이 실행될 때 자마 가상머신(JVM)에 의해 감지됨.

에러와 예외

  • 에러: 복구하기 어려운 수준의 심각한 오류.
    예. 메모리부족(OutOfMemoryError), 스택오버플로우(StackOverflowError)
  • 예외: 잘못된 사용 또는 코딩으로 인한 상대적으로 미약한 수준의 오류로서 코드 수정 등을 통해 수습이 간으한 오류

예외 클래스의 상속 계층도


자바의 모든 에러와 예외 클래스는 Throwable 클래스로부터 확장되며, 모든 예외의 최고 상위클래스는 Exception 클래스임. 모든 예외의 최고 상위 클래스인 Exception 클래스는 다시 크게 일반 예외 클래스와 실행 예외 클래스로 나눌 수 있음.

일반 예외 클래스(Exception)

런타임시 발생하는 RuntimeException 클래스와 그 하위 클래스를 제외한 모든 Exception 클래스와 그 하위 클래스들을 가리킴. 컴파일러 코드 실행 전에 예외 처리 코드 여부를 검사한다고하여 checked 예외라 부르기도 함. 주로 잘못된 클래스명(ClassNotFoundException)이나 데이터 형식(DataFormatException) 등 사용자편의 실수로 발생하는 경우가 많음.

실행 예외 클래스(Runtime Exception)

런타임 시 발생하는 RuntimeException 클래스와 그 하위 클래스를 지칭함. 컴파일러가 예외 처리 코드 여부를 검사하지 않는다는 의미에서 unchecked 예외라고 부르기도 함. 주로 개발자의 실수에 의해 발생하는 경우가 많고, 자바 문법 요소와 관련이 있음.
예. 클래스 간 형변환 오류(ClassCastException), 벗어난 배열 범위 지정(ArrayIndexOutOfBoundsException), 값이 null인 참조변수 사용(NullPointerException) 등

try-catch문

try {
  // 예외가 발생할 가능성이 있는 코드를 삽입
}
catch (ExceptionType1 e1) {
  // ExceptionType1 유형의 예외 발생 시 실행할 코드
}
catch (ExceptionType2 e2) {
  // ExceptionType2 유형의 예외 발생 시 실행할 코드
}
finally {
  // finally 블럭은 옵셔널
  // 예외 발생 여부와 상관없이 항상 실행
}

try 블럭 안에는 예외가 발생할 가능성이 있는 코드를 삽임.
만약 작성한 코드가 예외 없이 정상적으로 실행되면 아래 catch 블럭은 실행되지 않고 finally 블럭이 실행됨.
finally 블럭은 옵션으로 필수적으로 포함되지 않아도 되지만, 만약 포함되는 경우에는 예외 발생 여부와 상관없이 항상 실행하게 됨.
catch 블럭은 예외가 발생하는 경우 실행되는 코드로, 여러 종류의 예외 처리를 할 수 있음.
모든 예외를 받을 수 있는 Exception 클래스 하나로 처리도 가능하며, 각기 다른 종류의 예외를 하나 이상의 catch 블럭을 사용하여 처리할 수도 있음.
만약 catch 블럭이 여러개인 경우, 일치하는 catch 블럭만의 실행되고 예외처리 코드가 종료되거나 finally블럭으로 넘어가게 됨.
만약 일치하는 블럭을 찾지 못하는 경우에는 예외는 처리되지 못함.

예외 전가

try-catch문 외에 예외를 호출한 곳으로 다시 예뢰를 떠넘기는 부분

반환타입 메서드명(매개변수, ...) throws 예외클래스1, 예외클래스2, ... {
	...생략...
}
public class ThrowExceptionTest {

    public static void main(String[] args) {
        try {
            throwException();
        } catch (ClassNotFoundException e) {
            System.out.println(e.getMessage());
        }
    }

    static void throwException() throws ClassNotFoundException, NullPointerException {
        Class.forName("java.lang.StringX");
    }
}

//출력값
java.lang.StringX

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

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

throws 키워드와 유사한 throw 키워드를 사용하면 의도적으로 예외를 발생시킬 수 있음.

public class ExceptionTest {

    public static void main(String[] args) {
        try {
            Exception intendedException = new Exception("의도된 예외 만들기");
            throw intendedException;
        } catch (Exception e) {
            System.out.println("고의로 예외 발생시키기 성공!");
        }
    }
    
}

//출력값
고의로 예외 발생시키기 성공!

0개의 댓글