티스토리 뷰

개인공부/JAVA

Exception - throws (학교공부)

날따라해봐요요롷게 2021. 9. 17. 14:50

thorws (예외전파) 그냥 throws라고 하고 예외를 호출한 곳으로 다시 던진다고 표현을 했는데 예외를 전파한다는 표현으로 학교에서는 수업을 진행한다.

 

class ExceptoinAAA extends Exception{};
class ExceptoinBBB extends Exception{};

public class ExceptPropagation {
	public static void a() throws ExceptoinAAA,ExceptoinBBB  {
		System.out.println("a메소드 시작");
		b();
		throw new ExceptoinAAA();
	}
	public static void b() throws ExceptoinBBB{
		System.out.println("b메소드 시작");
		throw new ExceptoinBBB();
	}
	
	public static void main(String[] args) {
		try {
			System.out.println("main 메소드 시작");
			a();
		}catch(ExceptoinAAA e1) {
			System.out.println("예외 AAA 발생!");
		} catch(ExceptoinBBB e2) {
			System.out.println("예외 BBB 발생!");
		}
	}
}
==================================================================
main 메소드 시작
a메소드 시작
b메소드 시작
예외 BBB 발생!

 

위의 코드를 살펴보자

위 사진은 코드의 흐름을 보여준다.

Main 메소드에서 a메서드를 호출한다. a 메서드는 b메서드를 호출하고, A예외를 일으킨다.

호출된 b메서드는 B예외를 일으킨 후 해당 예외를 호출된 곳으로 예외를 전파한다. 즉 예외를 던진다.

--> 호출한 곳은 a메서드 이므로 a메서드가 일어난 B예외를 처리해야한다. 하지만 a메서드 또한 A,B 예외를 모두 예외전파한다. 즉 예외를 호출한 곳으로 던진다. --> a메서드를 호출한 main 메서드로 B예외를 던진다.

후에 main 메서드에서 던져진 B예외를 예외처리한다.

 

여기서 주목해야할 점은 흐름은 이해하기 쉽다는 것이다. 하지만 a()메서드 에서 생성한 A예외가 발생하지 않았다는 것이다. 그 이유는 자바는 하나의 예외가 발생하게 되면 해당 예외를 처리하기 위해서 다음 코드를 실행하지 않는다.

 

class ExceptoinAAA extends Exception{};
class ExceptoinBBB extends Exception{};

public class ExceptPropagation {
	public static void a() throws ExceptoinAAA  {
		System.out.println("a메소드 시작");
		throw new ExceptoinAAA();
	}
	public static void b() throws ExceptoinBBB{
		System.out.println("b메소드 시작");
		throw new ExceptoinBBB();
	}
	
	public static void main(String[] args) {
		try {
			System.out.println("main 메소드 시작");
			a();
            	b();
		}catch(ExceptoinAAA e1) {
			System.out.println("예외 AAA 발생!");
		} catch(ExceptoinBBB e2) {
			System.out.println("예외 BBB 발생!");
		}
	}
}
====================================================
main 메소드 시작
a메소드 시작
예외 AAA 발생!

위의 코드의 결과를 보면 main 메소드의 b() 메소드는 호출되지 않은 것을 볼 수 있다.

따라서 예외가 발생하게 되면 발생한 예외를 모두 처리한 후 뒤의 코드는 실행되지 않는다.

 

throws 를 사용하는 이유

- 예외처리코드를 중복해서 작성하지 않아도 된다. 

 : try~catch 문을 계속해서 작성하지 않고 호출된 곳에서만 try~catch문으로 예외를 처리하도록 한다.

 

- 예외전파를 통해서 예외처리문장들을 한 곳에 모아놓고 예외처리를 하게되면 발생하는 예외들을 한눈에 파악하기 쉽다.

 

class FirstExcep extends Exception{}

class SecondExcep extends Exception{}

public class Exception4 {
	static void a() throws FirstExcep {
		System.out.println("a 예외 발생 전");
		throw new FirstExcep();
	}
	static void b() throws SecondExcep {
		System.out.println("b 예외 발생 전");
		throw new SecondExcep();
	}
	public static void main(String[] args) {
		try {
			a();
			b();
		}catch(FirstExcep e1) {
			System.out.println("a예외처리");
		}catch(SecondExcep e2) {
			System.out.println("b예외처리");
		}
	}
}
============================
a 예외 발생 전
a예외처리

메인함수에서 a(), b() 메소드를 모두 호출 하였지만, a() 메소드만이 실행이되고 예외처리를 하는 것을 볼 수 있다.

: 예외가 발생하는 경우 다음 메소드를 실행하지 않고 발생한 예외를 처리하고 메인함수를 끝낸다.

 

 

예제) 정수들의 사칙연산 수식을 입력받아 수식이 정상이면 결과 값을 출력하려고 한다 . 그런데 만일 입력데이터가 없으면 입력데이터가 없다는 예외를 발생 , 데이터가 정수가 아니면 숫자가 아니라는 예외 발생 , 연산자가 사칙연산이 아니면 연산자 예외를 , 수식의 사칙 연산 형식이 잘못되면 수식의 형식 오류를 발생시킨다 .

 

- 사용자 정의 예외 클래스 만들기

 : 입력데이터가 없는 경우 (EmptyData), 숫자가 아닌 경우 (NoNumber), 사칙연산자가 아닌 경우 (IsOper), 수식의 형식이 잘못된 경우 (NoOper)

 

- 예외를 일으키기 위한 클래스형 메소드 만들기

 : checkData (데이터가 입력이 되었는지 확인) , checkNumOper(입력받은 데이터가 3개가 맞는지 확인)

isOper(연산자가 올바르게 입력이 되었는지 확인), caculate(입력받은 값들을 계산)

class EmptyData extends Exception{}
class IsNumOper extends Exception{}
class IsOper extends Exception{}

public class Exception5 {
	
	static void checkData(int num) throws EmptyData {
		if(num == 0) throw new EmptyData();
		
	}
	static void checkNumOper(int num) throws IsNumOper{
		if(num != 3) throw new IsNumOper();
	}
	static void isOper(String oper) throws IsOper{
		// !(oper.equals("+") || oper.equals("-") || oper.equals("x") || oper.equals("/"))
		if(!(oper.equals("+") || oper.equals("-") || oper.equalsIgnoreCase("x") || oper.equals("/"))) {
			throw new IsOper();
		}
		
	}
	static void calculate(String args[]) throws NumberFormatException{
		int num1 = Integer.parseInt(args[0]); // ==> 여기서 입력된 숫자가 정수인지 아닌지 확인하는 예외가 발생한다.
		int num2 = Integer.parseInt(args[2]);
		String oper = args[1];
		double result = 0;
		
		switch(oper) {
		case "+" : result = num1 + num2;
		break;
		case "-" : result = num1 - num2;
		break;
		case "x" : result = num1 * num2;
		break;
		case "/" : result = num1 / num2;
		break;
		}
		
		System.out.println(num1 + oper + num2 + " = " + result);
	}
	
	public static void main(String[] args) {
		
		try {
			checkData(args.length);	//	데이터가 있는지 확인
			checkNumOper(args.length);	// 입력한 항이 3개인지 확인
			isOper(args[1]);	// 수식이 올바른지 확인
			calculate(args);
		} catch(EmptyData e1) {
			System.out.println("데이터가 없음!");
		} catch(IsNumOper e2) {
			System.out.println("입력 데이터가 3개가 아님");
		} catch(IsOper e3) {
			System.out.println("수식이 잘못 됨");
		} catch(NumberFormatException e4) {
			System.out.println("정수가 입력되지 않음");
		}
	}
}

해당 문제 코딩 시 isOper에서 연산자가 올바르게 입력되었는지 확인하기 위해서 문자열 메소드의 equals 메소드를 사용하여 비교를 한다. ==> oper.equals("+");

 

 

 

 

 

'개인공부 > JAVA' 카테고리의 다른 글

Exception - Runnable(학교공부)  (0) 2021.11.02
Thread - Sync  (0) 2021.09.10
Exception  (0) 2021.09.09
배열, 기본클래스  (0) 2021.05.05
JAVA - Inner Class, Lambda , Stream  (0) 2021.03.21
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함