Web Development/Java

예외처리 try ~ catch ~ finally 구문

seongduck 2022. 10. 11. 23:05
  • 예외 처리목적
  • try ~ catch ~ finally 구문을 이용한 예외 처리
  • throws 구문을 이용한 예외 처리
  • 사용자 정의 예외 처리

1. 예외 처리란?

  • 예상치 못한, 치명적인 상황이 발생할 때 시스템을 비정상적으로 종료되는 것을 막는 행위 (Exception)
int result = 10 / 0;
  • 이렇게 계산이 되지 않는 상황에 예외 처리를 실시한다.

2. 예외 클래스

  • Checked Exception
    • 컴파일 시에 예외 처리를 해 주었는지 체크하는 Exception (빨간 밑줄 - 쉽게 확인할 수 있음)
    • IOException
  • Unchecked Exception
    • 프로그램 실행 중에 발생하는 Exception (코드 작성때 유의해야 한다. - 쉽게 발견할 수 없음)
    • ArithmaticException

 

2-1 자주 발생하는 Exception 종류

Exception 종류 설명
*ArithmeticException  산술 연산 중, 0으로 나누었을 때 발생
*NumberFormatException 숫자로 변경될 수 없는 문자열을 숫자로 변경하려고 시도하는 경우 발생
*NullPointerException 참조 데이터형 변수의 값이 null인데 객체에 접근하려고 하는 경우 발생

ex) Student를 null로 설정했는데 이를 객체로 사용할 경우
*ArrayIndexOutOfBoundsException 배열의 범위를 벗어난 인덱스에 접근하려고 할 때 발생

ex) 크기가 4인 배열에 5번째 요소를 접근할 경우
*ClassCastException 체의 형 변환 시, 잘못된 클래스로 변환하려고 할 때 발생

3. try ~ catch ~ finally

기본적인 try ~ catch 형태

try {
	//Exception이 발생할 가능성이 있는 구문
	} catch(Exception_클래스_타입 변수명) {
	//Exception이 발생했을 경우 수행해야 하는 문장
	}

 

  • 예제
try {
		int result = num1 / num2;
	} catch(ArithmeticException e) {
		System.out.println("num2는 0이 될 수 없습니다.");
	}
  • num2가 0이 될 가능성이 있으므로 try 구문에 넣어준다.
  • 이 경우 발생하는 Exception은 ArithmeticException이므로 클래스 타입 변수명은 다음과 같이 넣어준다.

 

try

  • Exception이 발생할 가능성이 있는 코드를 try블록으로 감싼다.
  • try 블록 안에 있는 문장들은 Exception이 발생하지 않는 한, 모두 정상 수행된다.
  • Exception이 발생하면, 즉시 발생한 Exception 객체를 catch 블록으로 전달한다.

 

catch

  • Exception 객체를 받아서, 예외 상황이 발생했을 때 수행할 일들을 작성해 준다.
  • 여러 가지 Exception 클래스 타입들 중, 발생 가능성이 있는 클래스 객체를 선언해준다.

4. 예제

  • Student 클래스
package chapter12;

public class Student {
	private String classname;
	private String name;
	
	Student(String classname, String name){
		this.classname = classname;
		this.name = name;
	}

	public String getClassname() {
		return classname;
	}

	public void setClassname(String classname) {
		this.classname = classname;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	

}

 

  • ExceptionBasicEx Class
package chapter12;

public class   {

	public static void main(String[] args) {
		Student[] students = new Student[5];
		students[0] = new Student("STU001", "홍길동");
		students[1] = new Student("STU002", "홍길순");

		for(int inx = 0; inx < students.length; inx++) {
			try {
				System.out.println(students[inx].getName());
			} catch (NullPointerException e) {
				System.out.println("값이 null입니다.");
			}
		}
	}

}
//출력 결과
홍길동
홍길순
값이 null입니다.
값이 null입니다.
값이 null입니다.

 

4-1 예제

  • 수강생 4명의 이름을 출력하려고 한다.
  • 이름정보는 배열에 담아 관리, 반복문을 이용하여 각 배열 요소에 접근한다.
  • 그런데 실수로 인덱스 0~3번이 아닌 14번까지 반복문을 작성하게 되었다.
  • 이때 발생하는 Exception과 처리를 위해서 어떻게 하는지 작성해보자.
package chapter12;

public class PrintNameTest {

	public static void main(String[] args) {
		String[] names = {"전우치","홍길동","홍길순","임꺽정"};
		
		for(int i = 1; i<=names.length; i++) {
			try {
				System.out.println(names[i]);
			} catch(ArrayIndexOutOfBoundsException e) {
				System.out.println("에러!! 잘못된 경로");
			}
		}
	}
}
//출력 결과
홍길동
홍길순
임꺽정
에러!! 잘못된 경로

5. 여러 형태의 Exception이 발생하면?

try {
	//Exception이 발생할 가능성이 있는 구문
	} catch(Exception_클래스_타입 변수명) {
	//Exception이 발생했을 경우 수행해야 하는 문장
	} catch(Exception_클래스_타입2 변수명){
    	//Exception2가 발생했을 경우 수행해야 하는 문장
    }
  • 위에서부터 내려오므로 (else if 개념) 위에서 예외상황이 걸리면 아래부분을 실행하지 않고 넘어가게 된다.
  • 하위 클래스의 예외부터 상위 클래스의 예외 순서로 작성
  • Exception이 발생하면 위에서부터 차례대로 검사하면서 알맞은 catch 블록을 찾아 수행
  • 제일 마지막에는 최상위 Exception 클래스를 작성하여 모든 예외 사항을 처리할 수 있음.

6. 반드시 수행되는 Finally

  • try 블록 안 코드의 Exception 발생 유무와 상관 없이 반드시 수행해야 하는 문장
  • catch 블록이 모두 끝난 후 finally 블록을 작성
try {
	//Exception이 발생할 가능성이 있는 구문
	} catch(Exception_클래스_타입 변수명) {
	//Exception이 발생했을 경우 수행해야 하는 문장
	} finally{
    	//반드시 수행해야 하는 문장
    }
  • 예외가 발생하건 안하건 꼭 수행되야 한다.

 

6-1. 예제

  • 100을 -3부터 3까지 순차적으로 나누어 결과를 출력한다.
  • 나누기 연산은 Exception이 발생할 여지가 있으므로 예외 처리를 한다.
  • 연선을 한 번 수행할 때마다 구분자로 "--------" 문자열이 무조건 출력되도록 하자.
package chapter12;

public class DivideTest {

	public static void main(String[] args) {

		for(int i = -3; i<=3; i++) {
			try {
				int result = 100/i;
				System.out.println("100 /" + i + " = " + result);
			} catch(ArithmeticException e) {
				System.out.println("잘몬된 연산 발생!!");
			} finally {
				System.out.println("----------------");
			}
		}
	}

}
//출력 결과
100 /-3 = -33
----------------
100 /-2 = -50
----------------
100 /-1 = -100
----------------
잘몬된 연산 발생!!
----------------
100 /1 = 100
----------------
100 /2 = 50
----------------
100 /3 = 33
----------------

 

6-2. 실습

  • arrayOne, arrayTwo라는 2개의 배열이 있다.
  • 두 개의 배열에서 같은 인덱스 번호의 값을 추출하고, 첫 번째 배열의 값을 두 번째 배열의 값으로 나누기 연산한다.
  • 예외 상황이 발생하면 비정상적으로 종료되지 않도록 하고 작동하게 해보자.

 

package chapter12;

public class ArrayDivideTest {

	public static void main(String[] args) {
		int[] arrayOne = {10,20,13,25};
		int[] arrayTwo = {2,5,0,3};
		
		for(int i = 0; i< arrayOne.length; i++) {
			try {
				System.out.println(arrayOne[i] + " / " + arrayTwo[i] + " = " +
						(arrayOne[i] / arrayTwo[i]));
			} catch (ArithmeticException e) {
				System.out.println("나누기 연산 시 에러가 발생하였습니다. ");
			}
		}
	}
}
//출력 결과
10 / 2 = 5
20 / 5 = 4
나누기 연산 시 에러가 발생하였습니다. 
25 / 3 = 8

'Web Development > Java' 카테고리의 다른 글

예외 처리 - 사용자 정의 예외  (0) 2022.10.11
예외 처리 - throws 구문  (0) 2022.10.11
HashMap  (0) 2022.10.08
List Collection  (0) 2022.10.08