S E P H ' S

JAVA Exception 처리 방식 본문

Programing & Coding/JAVA

JAVA Exception 처리 방식

yoseph0310 2021. 2. 21. 16:19

Exception 처리를 할 때 주의해야하는 점이 있다.

1. 부모클래스가 예외가 없는데 부모클래스를 상속하는 자식클래스가 예외를 가질 수는 없다.

2. 자식클래스가 부모클래스보다 범위가 넓은 예외를 가질 수 없다. 같거나 작은 범위의 예외만 가능하다.

 

Try / Catch / Finally

public class 예외처리예제 {

	public static void main(String[] args) {
		int [] arr = { 0, 1, 2 };
		
		try {
			System.out.println("마지막 원소 => " + arr[3]);
			System.out.println("첫번째 원소 => " + arr[0]);
		}
		catch( ArrayIndexOutOfBoundsException e ) {
			System.out.println("원소가 존재하지 않는다.");
		}
		System.out.println("호호");
	}

}

arr[3]은 Array의 인덱스를 범위를 벗어난 값이다. try에서 코드를 실행하고 오류가 발생하면 catch 문에서 오류를 잡아내고 catch 구문에 있는 syso를 실행하여 "원소가 존재하지 않는다."를 출력하고 맨밑의 출력물을 출력한다. try문에서 여러개의 예외가 발생할 수 있지만 동시에 발생하지는 않으므로 arr[0]을 출력하는 코드는 이전 코드에서 예외가 발생했으므로 실행되지 않는다.

 

- 하나의 try 문에서 여러개의 예외가 발생할 수 있지만 동시에 발생하지는 않는다.

- 하나의 예외가 발생하면 즉시 try블록의 실행을 멈추고 catch블록을 실행한다.

- 예외 발생여부와 관계 없이 무조건 수행할 실행문이 있다면 finaly블록을 추가하여 사용하면 된다.

 

 

public class 다중캐치블록 {

	public static void main(String[] args) {
		int divided = 10;
		
		try {
			int divisor = Integer.parseInt(args[0]);
//			int divisor = 0;
			System.out.println(divided / divisor);
		} 
		catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("원소가 존재하지 않는다.");
		} 
		catch (NumberFormatException e) {
			System.out.println("숫자가 아니다.");
		} 
		catch (ArithmeticException e) {
			System.out.println("0으로 나눌 수 없다.");
		} 
		finally {
			System.out.println("항상 실행된다.");
		}
		System.out.println("종료");

	}

}

다중 catch블록일 때 catch 순서

- 다중 catch블록일 때 try 블록에서 예외가 발생 했다면 그 예외를 catch블록 순서대로 비교

- 앞에 있는 catch 블록의 예외 객체가 나중 catch 블록 예외 객체의 부모라면 앞에 있는 catch블록이 먼저 가로채게 된다.

- 즉, 자식 예외 객체를 먼저 catch 해주고 순서대로 catch 블록에 작성해야한다. (구체적인 예외를 먼저 처리를 해야한다.)

 

 

예외 떠넘기기

메소드에서 발생한 예외를 내부에서 처리하기가 부담스러울때는 throws 키워드를 사용하여 예외를 상위코드 블록으로 양도 가능하다. 메소드에서 처리하지 않은 예외를 떠넘겨서 그 메소드를 호출한 곳에서 처리하게 할 수 있다. 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class 예외떠넘기기 {

	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		int N = Integer.parseInt(br.readLine());
	}

}

위의 코드 처럼 throws 키워드를 사용한다. 예외를 1개 이상 선언할 수 있고 throws는 예외를 다른 메소드로 떠넘기는 것이다.

public class 예외throw {
	public static void method1() {
		try {
			method2();
		}
		catch(ClassNotFoundException e) {
			System.out.println("클래스 없음.");
		}
	}
	
	public static void method2() throws ClassNotFoundException {
		Class clazz = Class.forName("java.lang.String2");
	}
	
	public static void main(String[] args) {
		method1();
	}
}

method2에서 ClassNotFoundException이 발생하지만 이를 throws 키워드로 떠넘겼다. 이는 method2를 호출한 method1에서 try, catch구문으로 처리했고 main 메소드에서 method1을 호출하면 "클래스 없음"을 출력하게 된다.

 

주의 사항

- throws 절이 있는 메소드를 오버라이딩 할 때는 메소드에 선언한 예외보다 더 광범위한 검사형 예외 (일반 예외)를 던질 수 없다.- 부모 클래스의 메소드에 예외를 떠넘기는 throws 절이 없다면 자식 클래스의 메소드를 오버라이딩 할 때 어떤 예외도 떠넘길 수 없다.

 

Exception을 상속받은 CustomException 을 사용하여 사용자가 조건을 만들어 throw로 하나의 예외를 던지고 method에서 throws 키워드로 CustomException을 떠넘겨서 사용할 수도 있다. 만약 사용자가 CustomException을 사용하려 할 때, CustomException의 용도가 기존의 Exception의 성질과 비슷하다면 그것을 사용하는것이 더 나을수도 있다.

 

'Programing & Coding > JAVA' 카테고리의 다른 글

[Java] 1. Java, 왜 사용할까?  (0) 2021.12.17
Comparable, Comparator  (0) 2021.02.21
JAVA Exception  (0) 2021.02.21
변수의 초기 값(Default Values)  (0) 2021.02.21
생성자(Constructor)  (0) 2021.02.21