[이것이 자바다] 예외 처리 (Chapter. 11)

hhyeong_0·2023년 9월 10일
0

예외와 예외 클래스

컴퓨터 하드웨어의 고장으로 인해 응용프로그램 실행 오류가 발생하는 것을 자바에서는 Error라고 한다.
프로그램을 아무리 견고하게 만들어도 개발자는 이런 오류에 대처할 방법이 전혀 없다.

자바에서는 에러 이외에 Exception이라고 부르는 오류가 있다. 예외란 잘못된 사용 또는 코딩으로 인한 오류를 말한다.
예외가 발생되면 프로그램은 곧바로 종료된다는 점에서는 에러와 동일하지만, 예외 처리를 통해 계속 실행 상태를 유지할 수 있다.

이러한 예외에는 다음 두 가지가 있다.

  • 일반 예외 (Exception)

    : 컴파일러가 예외 처리 코드 여부를 검사하는 예외를 말한다.
  • 실행 예외 (Runtime Exception)

    : 컴파일러가 예외 처리 코드 여부를 검사하지 않는 예외를 말한다.

위 그림의 모든 예외 클래스는 표준 라이브러리에서 제공하는 것들이다.

그림에서 볼 수 있듯 실행예외RuntimeExceptionRuntimeException의 자식 클래스가 속해있다.
그 밖의 예외 클래스는 모두 일반 예외이다.


예외 처리 코드

: 예외가 발생했을 때 프로그램의 갑작스러운 종료를 막고 정상 실행을 유지할 수 있도록 처리하는 코드
try - catch - finally 블록으로 구성된다.

* finally 블록은 예외 발생 여부와 상관없이 try 블록과 catch 블록에서 return문 (메소드 종료)를 사용하더라도 항상 실행된다.

public class ExceptionHandlingExample2 {
	public static void printLength(String data) {
    	try {	
        	int result = data.length();	// data가 null일 경우 NullPointerException 발생
            System.out.println("문자 수: " + result);
        } catch(NullPointerException e) {
        	System.out.println(e.getMessage()); // 예외 정보를 얻는 3가지 방법 1	
            System.out.println(e.toString());	// 예외 정보를 얻는 3가지 방법 2
            e.printStackTrace();				// 예외 정보를 얻는 3가지 방법 3
        } finally {
        	System.out.println("[마무리 실행]\n);
        }
   }
}

위 코드에서 예외 정보를 얻는 3가지 방법이 있다.

- e.getMessage()

: 예외가 발생한 이유만 리턴

- e.toString()

: 다음과 같이 예외의 종류도 리턴

java.lang.NullPointerException: Cannot invok "String.length()" because "data" is null

- e.printStackTrace()

: 예외가 어디서 발생했는지 추적한 내용까지도 출력

java.lang.NullPointerException: Cannot invok "String.length()" because "data" is null
	at ch11.sec02.ExceptionHandlingExample2.printLength(ExceptionHandlingExample2.java:6)
	at ch11.sec02.ExceptionHandlingExample2.main(ExceptionHandlingExample2.java:20)

예외 종류에 따른 처리

: try 블록에는 다양한 종류의 예외가 발생할 수 있는데 이 경우, 다중 catch를 사용하면 발생하는 에외에 따라 예외 처리 코드를 다르게 작성할 수 있다.
catch 블록의 예외 클래스try 블록에서 발생된 예외의 종류를 말하는데, 해당 타입의 예외가 발생하면 catch 블록이 선택되어 실행된다.


예외 떠넘기기

: 메소드 내부에서 예외가 발생할 떄 try-catch 블록으로 예외를 처리하는 것이 기본이지만, 메소드를 호출한 곳으로 예외를 떠넘길 수도 있다. 이때 사용하는 키워드가 throws이다.

throws는 메소드 선언부 끝에 작성하는데, 떠넘길 예외 클래스를 쉼표로 구분해서 나열해주면 된다.

리턴타입 메소드명(매개변수, ...) throws 예외클래스1, 예외클래스2, ... {
}

예시

throw 키워드가 붙어있는 메소드에서 해당 예외를 처리하지 않고 떠넘겼기 때문에, 이 메소드를 호출하는 곳에서 예외를 받아 처리해야 한다.
아래에서 ClassNotFoundException을 throws하는 method2()의 예외를 method1()에서 호출할 때 처리하고 있다.

public void method1(){
	try {
    	method2();	// 1. method2() 호출
    } catch(ClassNotFoundException e) { // 3. 떠넘겨진 예외를 처리함
    	System.out.println("예외 처리: " + e.getMessage());
    }
}
public void method2() throws ClassNotFoundException {	// 2. 호출한 곳에서 예외처리를 하도록 떠넘겼음.
	Class.forName("java.lang.String2");
}

나열해야할 예외 클래스가 많을 경우에는 throws Exception 또는 throws Throwable 만으로 모든 예외를 간단히 떠넘길 수도 있다.

리턴타입 메소드명(매개변수, ...) throws Exception {}

사용자 정의 예외

예외 발생 시키기

사용자 정의 예외를 직접 코드에서 발생시키려면 throw 키워드와 함께 예외 객체를 제공하면 된다.
예외의 원인에 해당하는 메시지를 제공하고 싶다면 생성자 매개값으로 전달한다.

throw new Exception("예외메세지");
throw new RuntimeException("예외메세지");

throw된 예외는 직접 try-catch 블록으로 예외를 처리할 수도 있지만, 대부분은 메소드를 호출한 곳에서 예외를 처리하도록 throw 키워드로 예외를 떠넘긴다고 한다. (아래 예시 첨부)

void method() {
	try {
    	...
        throw new Exception("예외메시지");
    } catch(Exception e) {
    	String message = e.getMessage();
    }
}
void method() throws Exception {
	...
	throw new Exception("예외메세지");
	...
}

참조:
이것이 자바다 교육 현장에서 가장 많이 쓰이는 JAVA 프로그래밍의 기본서 [ 개정판 ] - 신용권, 임경균 저 | 한빛미디어

profile
배우고 기록하자 !

0개의 댓글