본문 바로가기
국비지원/JAVA

[JAVA] 18. 예외처리문법 (try-catch 와 try-catch-finally / throws 와 throw keyword)

by cosmog 2022. 10. 17.
반응형
예외처리에 대하여

기본적으로 크게 두가지 error 상황이 있다.

 

1. 문법적으로 틀린 error (컴파일러 check 예외) -> 코드를 수정하면 해결가능
2. runtime error (실행 예외) -> 예외처리를 해주어야 피할 수 있다.
: 컴파일과정에서 발생되는 에러.

 

Try - Catch

 try~catch
- 에러가 없다면 try 영역실행
- 에러가 발생하면 catch영역 실행

 

Try - Catch문 기본 사용

public class TryCatchEx01 {

	public static void main(String[] args) {
		
		int a = 10;
		int b = 0;
		
		System.out.println(a+b);
		System.out.println(a-b);
		
		try {
			System.out.println(a/b);
			System.out.println("실행 될까?");
			
		//catch 뒤에는 해당 예외를 처리할 수 있는 예외 종류가 들어갑니다.
		} catch (Exception e) {
			System.out.println("0으로 나눌 수 없습니다");
		}
		System.out.println(a%b);
		
	}
}

Try - Catch문 배열 사용

public class TryCatchEx02 {
	
	public static void main(String[] args) {
		
		String[] arr = {"홍길동", "이순신", "홍홍홍"};
		
		int i = 0;
		while( i < 4 ) {
			try {
				System.out.println(arr[i]);
			}catch (Exception e) {
				System.out.println("범위를 벗어났습니다.");
			}finally {
				System.out.println("항상 실행되는 finally");
			}
			i++;
		}
	}

}

While문과 Try - Catch문 사용

import java.util.Scanner;

public class TryCatchEx03 {

	public static void main(String[] args) {
		
		//입력과 예외처리
		//0을 입력하기 전까지 숫자를 입력.
		
		Scanner scan = new Scanner(System.in);
		
		while(true) {
			try {
				System.out.print(">");
				int num = Integer.parseInt(scan.nextLine()); //정수를 받음 2번 해결방법
				//BufferReader bf = new BufferedReader(new InputStreamReder(System.in, "utf-9"));

				//1번 해결방법 : int num = scan.nextInt(); //정수를 받음
				if(num == 0) break;
				
			} catch (Exception e) {
				System.out.println("정수를 입력해줘");
				//1번 해결방법 : scan.nextLine();
				//continue;
			}
			
		}
		
	}
}

 

 try~catch~finally
- 에러가 없다면 try 영역실행 후 finally 실행
- 에러가 발생하면 catch영역 실행 후 finally 실행
-> finally는 try도 catch도 모두 실행한다. (반드시 실행해야하는것들)

 

다중 catch(두개 이상의 예외처리)
- else if처럼 계속 연결해서 catch ... catch 나올 수 있다.
Exception은 예외클래스들의 부모클래스이다.

public class MultiCatchEx01 {
	
	public static void main(String[] args) {
		
		/*
		 * main에 args 사용방법
		 * run > run configration > argments탭에 >${string_prompt}
		 */

		try {
			String data1 = args[0];
			String data2 = args[1];
			
			int n1 = Integer.parseInt(data1);
			int n2 = Integer.parseInt(data2);
			
			System.out.println("두 수의 합:" + (n1 + n2));
			
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("매개값은 2개 입력하세요");
		} catch (NumberFormatException e) {
			System.out.println("매개값은 숫자로 입력하세요");
		} catch (Exception e) { 
			//어떤 실행 예외든 처리가 가능 (예외 클래스들의 부모)
			//ctrl + t로 클래스 상하관계를 볼 수 있다.
			System.out.println("기타 예외 입니다");
		}
		
	}
}

 

throws keyword

method 뒤에 thorws 키워드를 사용하여 예외발생된 것을 다른 method에서 받도록 던질 수 있다.

package day18.exception.throws_;

public class ThrowsEx01 {
	
	public static void main(String[] args) {
		
		//method에서 예외처리 - throws
		//throws 구문이 붙어있는 method or 생성자를 호출할 때는 예외를 대신 처리해야 한다.
		//즉, method안에서 예외처리를 강요할 때 사용한다.
		/*
		greeting(0);
		greeting(1);
		greeting(2);
		greeting(3);
		greeting(4);
		*/
		
		/* greeting throws method */
		try {
			greeting(0);
			greeting(1);
			greeting(2);
			greeting(3);
			greeting(4);
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println("배열범위에서 벗어남");
		}
		
		System.out.println("----------------------------------------------");
		
		/* calc throws method */
		try {
			calc(1);
			calc(35);
			calc(3);
			calc(0);
			
		} catch (Exception e) {
			System.out.println("0으로 나눌 수 없습니다");
		}
		
		try {
			greeting(5);
		} catch (Exception e) {
			//예외처리를 하면 예외의 내용을 알수가 없기때문에,  
			// 예외의 내용을 확인하기 위해서 catch 영역에서는 항상 사용한다. 
			e.printStackTrace();
		}
		System.out.println("프로그램 정상종료");
	}

	//static variable
	private static String[] arr = {"안녕하세요", "hello", "니하오", "곤니찌와"};
	//static method
	public static void greeting(int index) throws Exception{
		System.out.println(arr[index]);
	}
	
	public static void calc(int num) throws ArithmeticException{
		System.out.println(10 / num);
	}
}

greeting과 calc method에서 발생하는 에러들은 throws 키워드를 통해 main method에서 실행할때 try catch를 통해 처리하도록 던저주고 있다.

package day18.exception.throws_;

public class Main {
	
	public static void main(String[] args) throws Exception{
		
		try {
			ThrowsEx02 ex = new ThrowsEx02();
		} catch (Exception e) {
			System.out.println("0으로 나눌 수 없습니다");
		}
	}

}
package day18.exception.throws_;

public class ThrowsEx02 {
	
	//생성자
	public ThrowsEx02() throws Exception{
		System.out.println("생성자호출");
		aaa();
		System.out.println("생성자종료");
	}
	
	public void aaa() throws Exception{
		System.out.println("aaa시작");
		bbb(1);
		System.out.println("aaa종료");
	}
	
	public void bbb(int i ) throws Exception{
		System.out.println("bbb시작");

		/*
		try {
			System.out.println(i / 0); //예외
		} catch (Exception e) {
		}
		*/
		System.out.println(i / 0); //예외
		//throws로 예외를 떠넘기면 예외가 발생한 그 자리에서 method가 종료된다고 보면된다.
		
		System.out.println("bbb종료");
	}

}
<결과값>
생성자호출
aaa시작
bbb시작
0으로 나눌 수 없습니다

에러가 발생한 시점부터 바로 호출된 method로 throws로 넘겨진다. 따라서 시작만 출력하고 종료는 출력하지 못한것이다.

 

throw keyword (위에 throws와는 다른것)
  • 예외를 강제로 직접 만들때 사용.
  • 예외를 강제로 발생시켜서 method를 강제 종료 시키도록 한다.

return값을 받는 method안에서 조건에 맞지않는 경우 예외처리를 해주려고 할때 강제로 return;하고 종료해줄 수 없다. 따라서 throw키워드를 사용하여 강제 종료하고 + 예외처리 구문을 전달해 줄 수 있다.

public class ThrowEx01 {
	
	public static void main(String[] args) {
		
		try {
			System.out.println(calc(10));
			System.out.println(calc(-10));
		} catch (Exception e) {
			e.printStackTrace(); //예외의 내용을 로그로 출력해주는 기능.
			System.out.println(e.getMessage()); //예외 생성시에 만들어진 메세지를 확인할 수 있음.
		}
	}
	
	//잘못된 값이 전달되면 예외를 만들어서 method를 강제종료
	public static int calc(int n) throws Exception{
		
		if(n <= 0) {
			throw new Exception("0이상으로 값을 전달하세요"); // 예외 강제 생성 - 예외를 생성하면 예외처리 구문이 필요하다.
			//return; 무조건 int형으로 값을 반환해 줘야해서 return을 종료를 시킬수 없다. 따라서 throw 키워드로 강제로 예외를 만들어서 종료시킨다.
		}
		
		int sum = 0;
		for(int i = 0; i <= n; i++) {
			sum += i;
		}
		return sum;
	}

}
반응형