프로그래밍/JAVA

25 예외처리(Exception)

윤지(●'◡'●) 2021. 4. 16. 23:05
반응형

 


예외처리(Exception)

 

자바 프로그램을 작성할 때 자바 문법에 맞지 않게 코드를 작성하고 컴파일하려고 하면, 자바 컴파일러는 문법 오류(syntax error)를 발생시킨다.

또한, 자바 문법에는 맞게 작성되었다 하더라도 프로그램이 실행되면서 예상하지 못한 오류가 발생할 수 있다.

이렇게 컴퓨터 시스템이 동작하는 도중에 예상하지 못한 사태가 발생하여,

실행 중인 프로그램이 영향을 받는 것을 오류(error)와 예외(exception) 두 가지로 구분할 수 있다.

 

오류(error) 시스템 레벨에서 프로그램에 심각한 문제를 야기하여 실행 중인 프로그램을 종료
예외(exception)

오류와 마찬가지로 실행 중인 프로그램을 종료시키지만,
발생할 수 있는 상황을 미리 예측하여 처리할 수 있다.

 

 

예외처리의 목적

 

목적1. Exception 발생 시 프로그램은 강제종료되기 때문에,
        이를 막기 위해서 try~catch문을 사용하여 예외 처리를 한다.

목적2. 시스템에서 발생하는 예외가 아닌 개발자가 직접 만든 예외를
         발생시키기 위해서(주로, 비속어 처리에서 씀)

 

 

예외처리 문법

 

try{

	예외를 처리하길 원하는 실행 코드;
    
}catch(예외이름 객체명){

	예외 발생 시 , 실행될 코드;
    
}....
finally {

    예외 발생 여부와 상관없이 무조건 실행될 코드;

}

 

try 블록 기본적으로 맨 먼저 실행되는 코드로 여기에서 발생한 예외는 catch 블록에서 처리된다.
catch 블록 try 블록에서 발생한 예외 코드나 예외 객체를 인수로 전달받아 그 처리를 담당한다.
finally 블록 try 블록에서 예외가 발생하건 안 하건 맨 마지막에 무조건 실행된다.

 

catch 블록과 finally 블록은 선택적인 옵션으로 반드시 사용할 필요는 없다.

필요에 따라 아래와 같은 구문으로 사용할 수 있다

(1) try~catch
(2) try~finally
(3) try~catch~finally

 

예외처리 메커니즘

 

 

Exception 클래스

 

 

자바에서 모든 예외의 조상 클래스가 되는 Exception 클래스는 크게 다음과 같이 구분할 수 있다.

 

1. RuntimeException 클래스
2. 그 외의 Exception 클래스의 자식 클래스

RuntimeException 클래스를 상속받는 자식 클래스들은 주로 치명적인 예외 상황을 발생시키지 않는 예외들로 구성된다.

따라서 try / catch 문을 사용하기보다는 프로그램을 작성하면서 예외가 발생하지 않도록 주의를 기울이는 편이 좋다.

 

하지만 그 외의 Exception 클래스에 속하는 자식 클래스들은 치명적인 예외 상황을 발생시키므로, 반드시 try / catch 문을 사용하여 예외를 처리해야만 합니다.

 

 

예외처리를 해보자 ( •̀ ω •́ )y

※ 예외처리할 문장 전체 영역잡고 > alt + shift + z 를 누르면 손쉽게 try~catch문을 생성할 수 있다.

 

 

1. 0으로 나누기를 하려 할 때

public class ExceptionTest {

	public static void main(String[] args) {
	
		try {
			System.out.println(10/0);
		} catch (ArithmeticException e) {
			System.out.println("수학적 예외 : 0으로 나눌 수 없습니다.");
		//	e.printStackTrace();
		}
		
	}
}

 

e.printStackTrace(); 
전체 에러 발생 경로 및 메시지를 출력 해준다.
즉, 단계별로 에러를 출력해 오류가 발생한 위치를 추적할수 있다.

 

2. 정수만 입력해야하는데 그 외의 값을 입력할 때

public class ExceptionTest2 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String msg = "정수만 입력하세요.";
		System.out.println(msg);
		try {
			System.out.println(sc.nextInt());
		} catch (InputMismatchException e) {
			System.out.println("정수만 입력하라구요~");
		} catch (Exception e) {
			System.out.println("다시");
		}
	}
}

 

정수만 입력하세요.
5 //입력
5 //출력
정수만 입력하세요.
안녕 //입력
정수만 입력하라구요~ //출력

 

3. "5개"의 정수만 입력 받기 , q입력시 나가기 
※ 입력 받은 정수는 모두 배열에 담는다

public class ExceptionTask {
	public static void main(String[] args) {
    
		System.out.println("정수를 입력하세요 :) , 그만하고 싶을 땐 q를 입력하세요");
		String msg = "정수 : ";
		Scanner sc = new Scanner(System.in);//Scanner 객체 생성
		String temp = null; // 입력 받은 값을 받을 변수 temp
		int [] arrData = new int[5]; // 값을 저장할 5칸 짜리 배열 생성
		int idx = 0; //받은 정수 갯수를 카운트할 변수 idx
		while (true) { // true인 동안 반복
			System.out.print(++idx + "번째 " + msg);
			temp = sc.next(); // 입력받은 정수 temp에 저장
			if(temp.equals("q")) {break;} // 만약 temp가 q라면 break(종료)
			try {
				arrData[idx-1] = Integer.parseInt(temp); // 받은값 정수로 형 변환하고 배열에 담기
				System.out.println("추가 성공 !");
			} catch (NumberFormatException e) { // 정수 외 다른타입 입력시 예외처리
				System.out.println("정수 또는 'q'만 입력 가능합니다.");
				idx--; // 잘못 입력한거니까 카운트 back
			} catch(IndexOutOfBoundsException e) { // 배열 칸 초과시 예외처리
				System.out.println("더이상 정수를 입력할 수 없습니다.");
				break; // 종료
			}
		}
		
		System.out.println("입력된 정수 : " + Arrays.toString(arrData));
		
	}
}

 

정수를 입력하세요 :) , 그만하고 싶을 땐 q를 입력하세요
1번째 정수 : 10
추가 성공 !
2번째 정수 : 20
추가 성공 !
3번째 정수 : 30
추가 성공 !
4번째 정수 : 40
추가 성공 !
5번째 정수 : 50
추가 성공 !
6번째 정수 : 60
더이상 정수를 입력할 수 없습니다.
입력된 정수 : [10, 20, 30, 40, 50]

 

정수를 입력하세요 :) , 그만하고 싶을 땐 q를 입력하세요
1번째 정수 : 10
추가 성공 !
2번째 정수 : 안녕
정수 또는 'q'만 입력 가능합니다.
2번째 정수 : 20
추가 성공 !
3번째 정수 : q
입력된 정수 : [10, 20, 0, 0, 0]

 

 

 

 

 

반응형