Tiny Bunny [JAVA] 멘토씨리즈 자바_SECTION.14 - 솜님의 블로그
솜님의 블로그
작성일
2024. 7. 28. 13:28
작성자
겨울솜사탕

예외 처리

 

에러(error)와 예외(exception)

자바 프로그램을 실행하다 보면 갑자기 프로그램이 종료되거나, 어떤 원인에 의해 잘못 동작하여 오류 메시지가 나타나는 등 오류가 발생한다.

전자는 우리가 해결할 수 없는 시스템에 에러가 발생해 프로그램이 종료된 경우,

후자는 프로그램 사용 중 발생한 오류를 개발자가 처리해 메시지가 출력된 경우이다.

 

자바는 에러 또는 예외가 발생한 경우, 해당 사항을 클래스로 관리한다.

 

 

에러(error)

에러는 시스템에 비정상적인 상황이 생겼을 때 발생한다.

외부 요인일 수도 있고, 구동 중 발생하는 오류일 수도 있다.

이러한 에러들은 개발자가 예측하거나 처리할 수 없는 영역이다.

 

에러의 종류

에러의 종류 상황
OutOfMemoryError 프로그램 실행 중 메모리 부족
IOError 입출력 에러
StackOverFlowError 가용 메모리 부족 현상, 재귀 호출 문제 시 발생

 

 

예외(exception)

예외란 대체로 프로그램 구동 중 나타나는 오류들을 말한다.

예외는 체크 예외(checked exception)와 비체크 예외(unchecked exception) 두 가지가 있다.

- 체크 예외 : 자바 소스 컴파일 하는 과정에서 검사, 보통 문법적으로 강제하여 예외처리 해야 하는 경우

- 비체크 예외 : 컴파일 과정에서 검사하지 않으므로 사용자의 경험이나 테스트로 찾아야 하는 경우

 

체크 예외와 비체크 예외 구분 기준

구분 체크 예외 비체크 예외
처리 여부 문법적으로 예외 처리를 강제함
반드시 처리 해야 함
문법적으로 강제하지 않음
개발자의 판단에 의해 처리
확인 시점 컴파일 단계 실행 단계
예외 클래스 Runtime Exception을 제외한 모든 예외
IOException
SQLException 등
Runtime Exception의 자식 클래스 모두 포함
NullPointerException
IndexOutOfBoundException
ClassNotFoundException 등

 

 

예외 클래스

자바는 객체 지향 언어로, 프로그램에서 발생하는 예외들은 클래스 형태로 제공된다.

 

▼예외 클래스의 구조

 

최상위의 Throwable을 상속받은 에러와 예외가 있다.

에러는 시스템상의 심각한 수준의 오류이기 때문에 수습될 수 없는 반면,

예외는 개발자가 로직을 추가하여 처리할 수 있다.

 

 

NullPointerException

자바 프로그램에서 가장 빈번하게 발생하는 실행 예외이다.

긱체가 제대로 생성되지 않은 상태에서 사용할 경우 발생한다.

public class NullPointExceptionExample{
	public static void main(String[] args){
    	
        // 배열을 변수 만들기만 하고 선언하지 않음
        String[] strArray = null;
        
        // 생성되지 않은 배열을 출력하려고 함
        System.out.println("staArray[0] = " + strArray[0]);
    
    }
}

 

 

NumberFormatException

잘못된 문자열을 숫자로 형 변환할 때 발생한다.

숫자 형태('111')의 문자열은 정수 타입으로 변환할 수 있으나,

문자가 포함되거나 실수 형태('11.11')의 문자열은 변환할 수 없다.

public class EX14_02{
	public static void main(String[] args){
    	
		String str01 = "11";
        String str02 = "11.2";
        
        // 정수 형태의 문자열을 정수로 반환
        int num01 = Integer.parseInt(str01);
        
        System.out.println("String to int : " + num01);
        
        // 실수 형태의 문자열을 정수로 변환
        int num02 = Integer.parseInt(str02);
        
        System.out.println("String to int : " + num02);
    
    }
}

str02의 "11.2" 때문에 오류가 발생한다.

이유는? 정수는 실수를 포함하지 않기 때문에 소수점(.)을 문자로 인식하기 때문이다.

 

 

ArrayIndexOutOfBoundsException

배열에서 인덱스(index) 범위를 초과해 사용할 때 발생한다.

public class EX14_03{
	public static void main(String[] args){
    	
        int[] arr = {1, 6, 7, 9, 10};
        System.out.println(arr[6]);
    
    }
}

 

 

 

 

예외 처리 문법

예외 처리 과정

🍀내부에서 발생하는 예외 처리 과정
1) 코드 진행 중 예외가 발생하면 JVM에게 알린다.
2) JVM은 발생한 예외를 분석하여 알맞은 예외 클래스를 생성한다.
3) 생성된 예외 객체를 발생한 지점으로 보낸다.
4) 예외가 발생한 지점에서 처리하지 않으면 프로그램은 비정상 종료된다.

 

따라서 넘어온 예외를 처리해 프로그램이 비정상으로 종료되지 않고, 구동할 수 있도록 해야 한다.

 

 

try-catch 구문

예외를 처리하는 가장 기본 문법이다.

try{
	//예외가 발생할 가능성이 있는 코드 작성
} catch(예외 클래스명 e){
	// 예외 처리 코드 작성
}

 

코드 진행 → 오류 → JVM예외 객체 발생 → catch 확인

발생한 예외를 처리하기 위해 try-catch 구문을 사용하게 된다.

예외 발생 가능성 있는 코드를 try{...}안에 작성하고, catch 메서드는 시스템으로부터 넘어오는 예외 클래스를 받아서 처리한다.

 

public class EX14_04{
	public static void main(String[] args){
    	int result = 0;
        
        try{
        	result = 10/0;
            System.out.println("나누기 결과" + result);
        } catch(ArithmeticException e){
        	System.out.println("0으로는 나누기를 할 수 없습니다.");
        }
        System.out.println("프로그램 종료");
    
    }
}

위 코드 중 result = 10/0 에서 오류가 발생한다. (정수 타입은 0으로 나눌 수 없기 때문)

나누기 관련 예외 처리는 ArithmeticException이 발생한다.

 

해당 예외가 발생되어 catch문으로 이동하게 되고, 위 코드의 실행결과는

- 0으로는 나누기를 할 수 없습니다.

- 프로그램 종료

 

++

예외를 처리할 때 Exception 클래스를 이용하면 모든 예외를 처리할 수 있다.

Exception은 모든 예외 클래스의 최상위 객체이기 때문이다.

 

다중 catch 사용하기

프로그램 구동 중 하나의 try 구문 안에서 다양한 예외가 발생할 수 있다.

이때 다중 catch문을 사용한다.

catch 문은 하나의 예외를 처리하도록 되어 있다. 코드에서 하나의 예외가 발생하면 그 위치에서 실행을 멈추고 해당 예외를 처리하는 catch 블록으로 이동하게 된다.

 

따라서 예외를 다중 처리하여 프로그램을 구성하면 다양한 예외를 처리할 수 있고, 보다 안정적인 프로그래밍이 가능해진다.

 

🍀다중 catch문 사용시 유의사항

다중 catch문을 사용할 때는 순서에 유의해야 한다.
Exception을 catch문 맨 앞에 사용하면 문법 에러가 발생한다.
이유는 Exception은 예외 객체 최상위 클래스이기 때문에 맨 앞에서 예외를 처리하게 되면, 뒤에 있는 다른 예외들은 불필요해지기 때문이다.
따라서 Exception처럼 상위 예외 클래스를 처리하는 코드는 catch문 맨 마지막에 작성한다.

 

 

 

finally

finally 블록은 예외 발생 유무와 상관없이 실행되는 구문이며, 생략 가능하다.

예외 처리를 할 때, 예외와 상관없이 반드시 처리해야 하는 구문들을 작성할 때 사용되며, 외부 연동이나 예외가 발생해도 정상 종료되어야 할 구문들에서 사용한다.

try{
	// 실행 코드
} catch(ArithmeticException e){
	// 예외 처리
} finally{

}

 

 

 

 

예외 던지기

메서드 내부에서 예외를 처리하지 않고 미룬 후, 해당 메서드를 호출한 쪽에서 예외를 처리하도록 하는 방법도 있다.

이것을 '예외 던지기' 또는 '예외의 전가'라고 한다.

 

throws 키워드

예외 던지기는 throws 키워드를 사용한다.

메서드 뒤에 throws 키워드를 사용하여 던지기 할 예외 객체를 붙여주면 된다.

여러 개를 던질 수 있으며, 여러 개 던질 시에는 콤마(,)로 구분하여 나열해 준다.

 

 

임의의 예외 처리 방법

프로그램 규칙에 위배되어 예외를 발생해야 하는 경우도 있다.

이때는 임의로 예외를 발생시킬 수 있다.

 

  • 정의 : 예외 발생 상황이 아니더라도, 필요에 의해 강제로 예외를 발생시키는 기능
  • 발생 방법 : throw new 예외 객체(메시지);
  • 발생 위치 : try-catch 내부 또는 메서드에 예외 던지기가 있는 경우
  • 용도 : 개발자가 예외를 의도하는 위치

 

 

사용자 정의 예외 처리

자바가 제공하는 예외 객체 외에도 개발자의 목적에 의해 예외 객체를 만들 수 있다.

목적에 따라 공통기능을 지니는 예외 처리도 필요하기 때문에 개발자가 직접 예외를 생성하여 처리한다.