KoreanFoodie's Study

10-1. 자바 예외처리 : 자바 예외처리 종류와 다중 catch, 멀티 catch 예제 본문

Tutorials/Java

10-1. 자바 예외처리 : 자바 예외처리 종류와 다중 catch, 멀티 catch 예제

GoldGiver 2021. 9. 19. 08:10

예외와 예외 클래스

JVM 실행에 문제가 생겼을 때, 우리는 에러를 마주하게 된다. 자바에서는 에러 이외에 예외(exception)라고 부르는 오류가 있는데, 예외란 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류를 말한다. 예외가 발생되면 프로그램은 곧바로 종료하지만, 예외 처리(Exception Handling)을 통해 프로그램을 종료하지 않고 정상 실행 상태가 유지되도록 할 수 있다.

예외는 두 가지 종류가 있다. 하나는 일반 예외(Exception)이고, 다른 하나는 실행 예외(Runtime Exception)이다. 일반 예외는 컴파일러 체크 예외라고도 하는데, 자바 소스를 컴파일 하는 과정에서 예외 처리 코드가 필요한지 검사하기 때문이다. 만약 예외 처리 코드가 없다면 컴파일 오류가 발생한다. 실행 예외는 컴파일 하는 과정에서 예외 처리 코드를 검사하지 않는 예외를 말한다. 컴파일 시 예외 처리를 확인하는 차이일 뿐, 두 가지 예외는 모두 예외 처리가 필요하다. 자바에서는 예외를 클래스로 관리하며, JVM은 프로그램을 실행하는 도중에 예외가 발생하면 해당 예외 클래스로 객체를 생성한다. 모든 예외 클래스들은 다음과 같이 java.lang.Exception 클래스를 상속받는다.

일반 예외와 실행 예외 클래스를 구별하는 방법은 일반 예외는 Exception을 상속받지만 Runtime Exception을 상속받지 않는 클래스들이고, 실행 예외는 다음과 같이 RuntimeException을 상속받은 클래스들이다. RuntimeException 역시 Exception을 상속받지만, JVM 은 RuntimeException을 상속했는지 여부를 보고 실행 예외를 판단한다.

 

실행 예외

실행 예외는 자바 컴파일러가 체크를 하지 않기 때문에 오로지 개발자의 경험에 의해 예외 처리 코드를 삽입해야 한다.

 

NullPointerException

객체 참조가 없는 상태, 즉 null 값을 갖는 참조 변수로 객체 접근 연산자인 도트(.)를 사용했을 때 발생한다.

String data = null;
data.toString();

 

ArrayIndexOutOfBoundsException

말 그대로, 배열에서 인덱스 범위를 초과하여 사용할 경우 발생한다.

int test[3] = {0};
test[4] = 1;

 

NumberFormatException

문자열을 숫자로 변환할 때 보통 Integer.parseInt( ), Double.parseDouble( ) 메소드를 사용하는데, 숫자로 변환될 수 없는 문자가 ( ) 안에 들어갈 경우 발생한다.

 

ClassCastException

타입 변환(Casting)은 상위 클래스롸 하위 클래스 간에 발생하고 구현 클래스와 인터페이스 간에서도 발생한다. 이러한 관계가 아니라면 클래스는 다른 클래스로 타입 변환할 수 없다.

// 상속 관계에 있는 것끼리는 문제가 없음
Animal animal = new Dog();
Dog dog = (Dog) animal;

RemoteControl rc = new Television();
Television tv = (Television) rc;

// 상속 관계에 있지 않음
Cat cat = (Cat) animal;
Audio audio = (Audio) rc;

 

예외 처리 코드

프로그램에서 예외가 발생했을 경우 갑작스러운 종료를 막고, 정상 실행을 유지할 수 있도록 처리하는 코드를 예외 처리 코드라고 한다. 예외 처리 코드는 try-catch-finally 블록을 이용한다. try-catch-finally 블록은 생성자 내부와 메소드 내부에서 작성되어 일반 예외와 실행 예외가 발생할 경우 예외 처리를 할 수 있도록 해준다.

try {

// 예외 발생 가능 코드

} catch(예외 클래스 e) {

// 예외 발생시 실행

} finally {

// 항상 실행

}
public class TryCatchFinallyExample {
	public static void main(String[] args) {
		try {
			Class clazz = Class.forName("java.lang.String2");
		} catch(ClassNotFoundException e) {
			System.out.println("클래스가 존재하지 않습니다");
		} finally {
			System.out.println("클래스 이름을 확인하세요");
		}
	}
}

 

예외 종류에 따른 처리 코드

 

다중 catch

try 블록 내부는 다양한 종류의 예외가 발생할 수 있다. 이 경우, 다중 catch 블록을 작성하면 아래와 같이 여러 예외를 잡을 수 있다.

public class TryCatchFinallyExample {
	public static void main(String[] args) {
		try {
			Class clazz = Class.forName("java.lang.String");
			int arr[] = {0,};
			arr[3] = 0;
		} catch(ClassNotFoundException e) {
			System.out.println("클래스가 존재하지 않습니다");
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("인덱스 크기를 확인하세요");
		} finally {
			System.out.println("예외 처리가 작동중입니다");
		}
	}
}

이 때, 예외를 처리하는 순서는 위에서부터 차례대로 내려온다. 따라서, 순서를 잘 지정해야 한다.

try {

// catch는 상위 클래스이므로, 무조건 실행!
} catch(Exception e) {

// 두번째 catch 블록에게 기회가 안 옴!
} catch (NumberFormatException e) {

}

위의 코드는, Exception과 NumberFormatException의 catch 블록 순서를 바꾸어 주어야 한다!

 

멀티 catch

자바 7부터 하나의 catch 블록에서 여러 가지 예외를 처리할 수 있도록 catch 괄호 ( )안에 동일하게 처리하고 싶은 예외를 | 로 연결하면 된다.

try {

} catch(ArrayIndexOutOfBoundsException | NumberFormatException e) {

// 예외 처리 코드

} finally {

}

해당 포스팅은 이것이 자바다 (신용권 저) 를 참고하였습니다

 

Comments