본문 바로가기

Java/Java

예외 처리_예외 처리

1. 예외 처리 코드

일반 예외와 실행 예외를 처리하기 위해 예외 처리 코드를 작성해야한다.

일반 예외의 경우, 컴파일러가 강제적으로 개발자에게 예외 처리 코드를 작성하도록 요구한다.

그러나 실행 예외의 경우, 컴파일러가 예최 처리 코드를 강제하지 않으며 개발자의 경험을 통해 예외 처리 코드를 작성해야한다.

 

 

2. try-catch-final 블록

try-catch-final 블록은 생성자 또는 메소드 내부에 작성되어 일반 예외와 실행 예외를 처리하기 위해 사용된다.

try-catch-final 블록의 형태와 실행 과정은 아래와 같다.

  • try { 예외 발생 가능 코드 } catch(예외클래스 e) { 예외 처리 코드 } final { 항상 실행 코드 }
  1. try 블록에는 예외가 발생할 수 있는 코드가 작성된다.
  2. try 블록 코드에서 예외가 발생하지 않는다면 catch 블록 코드는 실행되지 않고, 곧바로 final 블록 코드가 실행된다.
  3. 그러나 만약 try 블록 코드에서 예외가 발생한다면 catch 블록의 예외 처리 코드가 실행된다. 그 후에 final 블록 코드가 실행된다.
  4. final 블록의 작성은 생략이 가능하다. 예외 발생 여부와 상관 없이 항상 실행해야할 코드가 존재할 경우에만 작성해주면 된다. final 블록에는 항상 실행 코드가 작성되는데 말그대로 항상 실행되는 코드이다. try, catch 블록에서 return문이 실행되더라도 final 블록 코드는 항상 실행된다.

 

3. 예외 종류에 따른 처리 코드

예외 종류에 따라 예외 처리 코드 작성 방법이 다르다.

 

1) 다중 catch

try 블록 내부에는 한 종류의 예외가 아닌 다양한 종류의 예외가 발생할 수 있다. 

이런 경우, 예외의 종류에 따라 다르게 예외 처리를 하려면 다중 catch 블록을 사용하면 된다.

  • try { 예외 발생 가능 코드 } catch(예외클래스1 e) { 예외 처리 코드1 } catch(예외클래스2 e) { 예외 처리 코드2 } final { 항상 실행 코드 }

위의 코드처럼 catch 블록이 여러개 작성되더라도, 단 하나의 catch 블록만 실행된다.

그 이유는 try 블록에서 하나의 예외가 발생되면 즉시 실행이 멈추고, 발생 예외에 해당하는 catch 블록으로 이동하기 때문이다.

 

아래의 예제 코드를 살펴보자.

두 개의 catch 블록이 있으며 각각 ArrayIndexOutOfBoundsException, NumberFormatException예외를 처리한다. 

예외가 발생하면 각 예외를 처리하는 catch 블록이 실행되며, 그 후 final 블록이 실행된다.

package sec02.exam03;

public class CatchByExceptionKindExample {

	public static void main(String[] args) {
		try {
			String data1 = args[0];
			String data2 = args[1];
			int value1 = Integer.parseInt(data1);
			int value2 = Integer.parseInt(data2);
			int result = value1 + value2;
			System.out.println(data1 + "+" + data2 + "=" + result);
		} catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("실행 매개값의 수가 부족합니다.");
		} catch(NumberFormatException e) {
			System.out.println("숫자로 변환할 수 없습니다.");
		} finally {
			System.out.println("다시 실행하세요.");
		}

	}

}

 

2) catch 순서

다중 catch 블록을 사용할 때 주의할 점이 있다. 블록의 작성 순서를 기억해야한다.

상위 예외클래스를 처리하는 catch 블록이 하위 예외클래스를 처리하는 catch 블록보다 아래에 위치해야한다.

 

그 이유는 예외 처리 과정에 있다. 

try 블록에서 예외가 발생할 경우, 위에서 아래의 순서로 차례대로 catch 블록이 검색된다.

만약 상위 예외클래스에 대한 catch 블록이 위에 작성되어있다면, 하위 예외클래스에 대한 catch 블록이 별도로 작성되어 있더라도 상위 예외클래스에 대한 catch 블록이 실행된다.

그렇기 때문에 각각의 하위 예외클래스에 대한 catch 블록을 실행하기 위해서는 상위 예외클래스에 대한 catch 블록이 아래에 위치해야한다.

 

아래의 예제 코드를 보면 하위 예외클래스 ArrayIndexOutOfBoundsException에 대한 catch 블록이 먼저 작성되어 있고, 상위 예외클래스인 Exception에 대한 catch 블록이 아래에 작성되어 있다.

package sec02.exam01;

public class CatchOrderExample {

	public static void main(String[] args) {
		try {
			String data1 = args[0];
			String data2 = args[1];
			int value1 = Integer.parseInt(data1);
			int value2 = Integer.parseInt(data2);
			int result = value1 + value2;
			System.out.println(data1 + "+" + data2 + "=" + result);
		} catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("실행 매개값의 수가 부족합니다.");
		} catch(Exception e) {
			System.out.println("실행에 문제가 있습니다.");
		} finally {
			System.out.println("다시 실행하세요.");
		}

	}

}

 

 

3. 예외 떠넘기기

메소드 내부에서 예외가 발생할 수 있는 코드를 작성할 때는 try-catch 블록으로 처리하는 것이 기본이다.

그러나 경우에 따라서는 메소드를 호출한 곳으로 예외를 떠넘길 수도 있다.

이때 사용하는 키워드가 throws 키워드다. 

throws 키워드는 메소드 선언부 끝에 작성되어 메소드에서 처리하지 않은 예외를 호출한 곳으로 떠넘기는 역할을 한다.

  • 리턴타입 메소드이름(매개변수, ... ) throws 예외클래스1, 예외클래스2, ... { ... }

throws 키워드가 붙은 메소드는 반드시 try 블록 내에서 호출되어야 한다.

그리고 catch 블록에서 떠넘겨 받은 예외를 처리 해야한다.

 

아래의 예제 코드는 throws 키워드 사용의 예를 보여준다.

findClass메소드 내부에는 예외가 발생할 수 있는 코드가 작성되어 있다.

그리고 throws 키워드를 통해 ClassNotFoundException을 떠넘기고 있다.

 

그리고 findClass메소드는 throws 키워드를 갖고 있기 때문에 try 블록 내부에서 호출되고 있으며, catch 블록에서 떠넘겨진 ClassNotFoundException예외 클래스를 처리하고 있다. 

package sec02.exam02;

public class ThrowsExample {

	public static void main(String[] args) {
		try {
			findClass();
		} catch(ClassNotFoundException e) {
			System.out.println("클래스가 존재하지 않습니다.");
		}

	}
	
	public static void findClass() throws ClassNotFoundException {
		Class clazz = Class.forName("java.langString2");
	}

}

 

 

출처: 혼자 공부하는 자바(신용권)

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

스레드_스레드 제어  (0) 2022.04.03
스레드_멀티 스레드  (0) 2022.03.28
예외 처리_예외 클래스  (0) 2022.03.19
중첩 클래스 및 중첩 인터페이스_익명 객체  (0) 2022.03.13
중첩 클래스 및 중첩 인터페이스  (0) 2022.03.09