Java/모두의 자바

Chapter 09-48 예외(Exception)

계란💕 2022. 2. 11. 13:20

09-48.1 예외 처리

 

  Def) 예외: 프로그램 실행하는 과정에선 발생하는 예기치 못한 사건

 

  Ex 1)

<hide/>
package javaStudy;
public class ExceptionExam {
	public static void main(String[] args) {
		int i= 10;
		int j = 5;
		int k = i / j;
		System.out.println(k);
	}
}

  Note) 실행 결과: 2

 

  Ex 2) j = 0으로 바꾸면?

<hide/>
package javaStudy;
public class ExceptionExam {
	public static void main(String[] args) {
		int i= 10;
		int j = 0;
		int k = i / j;
		System.out.println(k);
	}
}

  Note) 실행 결과  "ArithmeticException"

  - 다른 명령을 추가해본다.

 

  Ex 3) 

<hide/>
package javaStudy;
public class ExceptionExam {
	public static void main(String[] args) {
		int i= 10;
		int j = 0;
		int k = i / j;
		System.out.println(k);
		System.out.println("main end!!");
	}
}

  Note) 실행 결과

  - 예제2번과 결과가 같다. 이처러 이후에 어떤 명령이 있어도 Exception이 발생하면 Exception 발생 지점 부터 

  - 프로그램을 종료해버린다.

  - 자바는 정수를 0으로 나눌 때 '예외'를 발생시킨다. 

 

 

09-48.2 컴파일 에러와 예외처리의 차이는?

 

  - 컴파일 에러는 문법이 맞지 않아 발생하는 오류이다. 

  - 예외는 실행 시점애서 잘못된 값으로 발생하거나 여러 상황에서 발생하는 "예기치 못한 사건"을 말한다. 

  - "예기치 못한 사건"이란?

    -> 레퍼런스 변수를 사용 시점에서 해당 변수가 적절한 객체를 레퍼런스 하지 않고 null을 가진경우

    -> 숫자 값이 들어와야하는데 문자 값이 들어오던가 하는 경우 

    -> 이런 상황을 미리 프로그래밍하지 않으면 컴퓨터는 아무것도 할 수 없다.

 

 

09-48.3 예외 처리 방법 

  - 자바는 예외처리 시 try - catch - finally 문을 사용한다. 

try {
	수행할 코드 , 예외 발생 가능성이 있는 블록
}catch (발생할 수 있는 예외타입 변수명) {
	예외 처리 블록
}finally {
	예외발생 여부 관계없이 무조건 발생시키는 블록(생략 가능)
}

  - try 블록 안에 오류와 관련된 Exceptionc타입을 catch블록에 처리한다.

  - catch블록 안에는 예외가 발생했을 때 처리할 수 있는 코드 넣는다.

  - try블록을 실행하면서 예외 객체가 발생하면 catch블록에서 해당 예외 객체를 catch해야 하는데 catch(예외타입변수명)에서 선언된 예외타입만 catch할 수 있다.

  - finally블록은 무조건 실행된다.

  - 원래 수행한 코드는 try 블록에 있다.

  - 그런데 try에서 예외가 발생하면 발생지점 부터 try 블록 마지막 까지는 실행할 수 없다.

  - catch블록에 선언해놓은 예외가 맞아야 해당 catch블록을 실행시킨다.

  - 따라서, try블록이나 catch블록이 반드시 실행할 거라고 예측할 수는 없다. (실행할 수도 있고 아닐수도 있다.)

  - finally는 반드시 실행하므로 중요하다. 

  - try블록에서 여러 종류의 예외가 발생한다면 catch 블록도 여러 개를 사용할 수 있다.

 

 

09-48.4 예외처리 예제

  (1) try-catch 구문

<hide/>
package javaStudy;
public class ExceptionExam {
	public static void main(String[] args) {
		int i= 10;
		int j = 0;
		try {
			int k = i / j;
			System.out.println(k);
		}
		catch( ArithmeticException e) {
			System.out.println("0으로 나눌 수 없습니다."+ e.toString());
		}
		System.out.println("main end!!");
	}
}

  Note) 실행 결과

 

  - 아까 예외가 발생하던 부분을 try 블록으로 감싼다.

  - catch문에는 예외타입인 "ArithmaticException"을 적고 변수명은 임의로 e입력한다.

  - 블록 안에는 예외가 발생했을 때 실행한 구문을 적는다.

  - System.out.println("0으로 나눌 수 없습니다."+ e.toString()) : 

    -> ArithmaticException라는 예외 객체를 e라는 참조변수가 가리킨다. 

    -> 그리고 e라는 참조변수를 toString이라는 메서드를 가진다. 

    -> toString 메서드는 예외 정보를 알려준다. 

    -> e.toString() : 예외 정보를 출력하라는 의미이다. 

 

  (2) finally 추가

<hide/>
package javaStudy;
public class ExceptionExam {
	public static void main(String[] args) {
		int i= 10;
		int j = 0;
		try {
			int k = i / j;
			System.out.println(k);
		}catch( ArithmeticException e) {
			System.out.println("0으로 나눌 수 없습니다."+ e.toString());
		}finally {
			System.out.println("예외와 상관 없이 무조건 실행!");
		}
		System.out.println("main end!!");
	}
}

  Note) 실행 결과

  -

 

09-48.5 예외처리 예제 (예외가 발생하지 않는 경우) 

 

  - 위의 예제에서 예외가 생기지 않도록 j = 5로 바꿨다.

<hide/>
package javaStudy;
public class ExceptionExam {
	public static void main(String[] args) {
		int i= 10;
		int j = 5;
		try {
			int k = i / j;
			System.out.println(k);
		}catch( ArithmeticException e) {
			System.out.println("0으로 나눌 수 없습니다."+ e.toString());
		}finally {
			System.out.println("예외와 상관없이 무조건 실행!");
		}
		System.out.println("main end!!");
	}
}

  Note) 실행 결과

   

  - 예외가 발생하지 않았기 때문에 catch블록은 실행하지 않는다.

  - 처음에는 예외가 발생해서 프로그램을 강제 종료했는데 catch블록으로 예외를 처리하니 잘 실행된다.

 

  Note) 예외 처리

  - 발생할 수 있는 예외가 너무 많고 각 예외마다 처리해야하는 코드가 다르면 catch블록을 여러개 사용한다.

  - 모든 예외 객체는 Exception클래스를 상속 받는다.

  - Exception클래스를 상속 받지 않은 클래스는 예외클래스가 될 수 없다.

  - 모든 예외클래스의 부모 클래스는 Exception클래스이다.

  - 따라서 다음과 같이 코드를 작성한다.

catch(Exception e) {
	System.out.println("예외 발생" + e.toString());
}

  - catch 블록의 발생가능 예외 클래스에 Exception이라고 두면 어떤 예외가 발생해도 하나의 catch문으로 예외처리 된다.

 

 

09-48.6 Exception 실습

 

  Ex) 다음 코드에서 Exception이 발생한다. 길이가 10인 배열에서 인덱스가 20인 값을 읽어오려 하기 때문이다. 

Exception이 발생하는 부분을 try-catch 문으로 감싸서 처리하려 한다. Exception이  발생하면 "배열의 범위를 지나쳤어요"라고 출력하고 다음 코드를 수행해서 '성공'을 출력하도록 코드 수정하라.

 

<hide/>
package javaStudy;
public class ExceptionExam {
	public static void main(String[] args) {
		int [] array = new int[10];
//정답	try {
//			array[20] = 5;	
//		}catch(Exception a) {
			System.out.println("배열의 범위를 지나쳤어요." );
		}
        System.out.println("성공");
	}
}

  - 10개 짜리 배열을 생성했는데 배열의 20번째 인덱스에 접근하려고 하므로 프로그램은 예외를 발생시킨다.

  - try-catch 구문을 이용해서 직접 처리한다.