티스토리 뷰
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 |