본문 바로가기

IT

16-1. 자바 예외처리 - try ~ catch

* 예외처리(Exception)

  • 에러에는 심각한 에러(serious error)와 가벼운 에러(mild error)가 있다. 심각한 에러는 시스템 상의 문제로 인한 에러로 개발자가 처리할 수 없는 에러다. 가벼운 에러는 개발자가 코드를 통해 처리할 수 있는 에러를 말한다. 이 방식을 예외 처리하고 한다.
  • 예외에는 컴파일러 체크 와 실행 예외(runtime exception)가 있다.
  • 컴파일러 체크 예외는 자바 소스를 컴파일하는 과정에서 예외 처리 코드를 검사하여 예외 처리 코드가 없다면 컴파일 오류가 발생한다.
  • 실행 예외는 컴파일하는 과정에서 예외처리 코드를 검사하지 않는 예외를 말한다.
  • 예외 처리는 컴파일 예외와 실행 예외에 대한 대처방법이다.
  • 예외 처리는 시스템 스스로 오류를 복구하는 것이 아니고 오류 발생 가능성이 있는 부분에 대한 처리를 미리 프로그래밍해주는거다. 
  • 프로그램에서 문제가 될만한 부분을 예상하여 사전에 "문제가 발생하면 이렇게 처리하라"라고 프로그래밍 하는것을 예외처리라고 한다. 

 

* 실행예외(Runtion Exception)

  • 실행 예외는 컴파일러가 예외 처리 코드를 체크하지 않기 때문에 오로지 개발자의 경험에 의해서 예외 처리 코드를 삽입해야한다.
  • 만약 개발자가 실행예외에 대해 예외처리 코드를 넣지 않을 경우 해당 예외가 발생하면 프로그램은 곧바로 종료된다.

- 주요 실행 예외

 

1. NullPointException

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

String str = null;
System.out.println(str.toLowerCase());

 

 

2.ArrayIndexOutOfBoundsException

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

int[] arr = {3, 6, 9};
System.out.println(arr[3]); //없는 배열 공간을 출력하려고 할때 에러 발생

 

3. NumberFomatException

문자열로 되어 있는 데이터를 숫자로 변경하는 경우에 발생된다.

	//문자열의 수치변환
		String a = "15";
		String b = "13";
		
		System.out.println(a + b);
		
		//Str -> int변환
		//Integer.parseInt(문자열)
		int i = Integer.parseInt(a);
		int j = Integer.parseInt(b);
		System.out.println(i + j);
		
		//parseInt는 문자열내부에 순수한 정수가 들어있어야만
		//변환을 실행하며 정수값이 아닐 경우 NumberFormatException
		//이 발생합니다.
		String str = "hello";
		System.out.println(Integer.parseInt(str));

 

4.ClassCastException

형 변환은 부모 클래스와 자식 클래스간에 발생하고 구현 클래스와 인터페이스 간에도 발생한다. 이러한 관계가 아니라면 다른 클래스로 타입을 변환할 수 없다.

상속관계나 인터페이스 관계가 없는 클래스들을 억지로 형 변환 할 경우 발생한다.

 

 

 


실습1. 예외처리

package exception.trycatch;

public class TryCatchExample1 {

	public static void main(String[] args) {
		
		int i = 10;
		int j = 0;
		
		System.out.println(i * j);
		
		try {  // 예외 발생 가능성이 있는코드
			System.out.println(i / j); 
			System.out.println("예외 발생시 이 텍스트는 출력되지 않음.");
		}catch (Exception e) {  //예외 발생 시 실행할 코드
			System.out.println("0으로 나눌 수 없습니다.");
		}
		
		System.out.println(i + j);
		System.out.println(i - j);
	}
}

* try ~ catch ~ finally

  • -프로그램에서 예외가 발생했을 경우 프로그램의 갑작스러운 종료를 막고, 정상 실행을 유지할 수 있도록 처리하는 코드를 예외 처리 코드라고 한다.
  • try ~ catch ~finally 블록은 생성자 내부나 메서드 내부에서 작성되어 컴파일 예외나 실행 예외가 발생할 경우에 예외 처리 할 수 있게 해준다.
  • try블록에는 예외 발생 가능성이 있는 코드를 작성한다. try블록의 코드가 예외 발생 없이 정상 실행되면 catch블록은 실행되지 않는다.
  • try내부에서 예외가 발생하면 즉시 실행을 멈추고 catch블록으로 이동하여 예외 처리 코드를 실행한다.
  • 예외 발생 여부와 상관없이 항상 실행할 내용이 있다면 finally블록 내부에 실행 내용을 작성한다.
finally구문이 실행되지 않는 경우

1. finally구문 이전에 system.exit()구문을 호출했을 시

2. 컴퓨터가 꺼져서 시스템이 멈추었을 경우

3. finally 블록 내부에서 예외가 발생했을 시 (내부에 try catch를 넣어줌)

 

실습. try ~ catch ~ finally

package exception.trycatch;

public class TryCatchExample2 {

	public static void main(String[] args) {
		
		String[] greetings = {"안녕", "헬로", "니하오"};
		
		int i = 0;
		while(i < 4) {
			try {
				System.out.println(greetings[i]);
			} catch(Exception e) {
				System.out.println("배열의 참조 범위를 벗어남!");
			} finally {
				System.out.println("이 문장은 항상 실행됨!");
			}
			i++;
		}
		System.out.println("프로그램 정상 종료!");
	}
}
---------결과---------
안녕
이 문장은 항상 실행됨!
헬로
이 문장은 항상 실행됨!
니하오
이 문장은 항상 실행됨!
배열의 참조 범위를 벗어남!
이 문장은 항상 실행됨!
프로그램 정상 종료!

* 다중 catch

try블록 내부는 다양한 종류의 예외가 발생하라 수 있다. 예외가 여러 가지 발생한다면 다중 catch블록을 작성하여 예외들을 처리한다.

 

다중 catch

package exception.multi;

import java.util.Scanner;

public class MultiCatchExample {

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		try {
			System.out.print("1번째 데이터: ");
			String data1 = sc.next();
			System.out.print("2번째 데이터: ");
			String data2 = sc.next();
			
			//NumberFormat 발생 가능!
			int val1 = Integer.parseInt(data1);
			int val2 = Integer.parseInt(data2);
			
			//Arithmetic 발생 가능!
			int result = val1 / val2;
			System.out.println(val1 + " / " 
						+ val2 + " = " + result);
			
			String str = null;
			str.charAt(0);
		
		//Exception클래스는 모든 예외를 일괄처리할 수 있습니다.
		} catch (NumberFormatException e) {
			System.out.println("숫자만 입력해주세요.");
		} catch (ArithmeticException e) {
			System.out.println("0으로 나눌 수 없습니다.");
		} catch (Exception e) {
			System.out.println("알 수 없는 예외 발생!");
			System.out.println("확인 후 신속히 처리하겠습니다.");
		} finally {
			sc.close();
		}
		System.out.println("프로그램 정상 종료!");

	}

}