쌍용교육센터 - 13일

개발자가 되고 싶어요 ㅣ 2024. 3. 6. 18:26

2024.03.06

https://tmddus3002.tistory.com/63

 

예외 처리

예외 처리 일반 예외(Exception) 컴파일러가 예외 처리 코드 여부를 검사하는 예외를 말한다. 실행 예외(Runtime Exception) 컴파일러가 예외 처리 코드 여부를 검사하지 않는 예외를 말한다. 예외 처리

tmddus3002.tistory.com

예외와 예외처리

  • 예상하지 못한 일들을 ‘예외’라 하고 이를 대비하고 준비하는 것이 바로 ‘예외처리’다.

 

예외처리에 대한 필요성과 이해

  • 자바에서 프로그램의 실행하는 도중에 예외가 발생하면 발생된 그 시점에서 프로그램이 바로 종료가 된다. 때에 따라서는 예외가 발생 했을 때 프로그램을 종료시키는 것이 바른 판단일 수도 있다. 하지만 가벼운 예외이거나 예상을 하고 있었던 예외라면 프로그램을 종료시키는 것이 조금은 가혹하다고 느껴진다. 그래서 **‘예외처리’**라는 수단이 제안되었고 예외 처리를 통해 우선 프로그램의 비 정상적인 종료를 막고 발생한 예외에 대한 처리로 정상적인 프로그램을 계속 진행할 수 있도록 하는 것이 예외처리의 필요성이라 할 수 있다.

 

오류의 구분

구분 설명
예외(Exception) 가벼운 오류이며 프로그램적으로 처리
오류(Error) 치명적인 오류이며 JVM에 의존하여 처리

 

예외의 종류

 

예외처리

  • try catch문을 사용하여 예외를 처리할 수 있다.
public class ExceptionMain02 {
	public static void main(String[] args) {
		int[] array = {10,20,30};
		/*
		 * 테스트용으로 없는 인덱스 3을 호출해서 예외를 발생시킴
		 * 예외가 발생하면 예외가 발생한 지점에서 프로그램이 강제로 종료됨
		 */
		for (int i = 0; i <= array.length; i++) {
			/*
			 * 예외가 발생하고 프로그램이 멈춤
			 * 예외가 발생하면 예외 정보를 담고 있는 예최 객체가
			 * 생성되고 예외 문구가 콘솔에 출력됨
			 */
			try {
				System.out.println("array["+i+"] : "+ array[i]);
			} catch(ArrayIndexOutOfBoundsException e) {
				System.out.println("배열의 크기를 벗어납니다.");
			}
		}
	}
}

 

다중 catch문

  • 다중 catch문은 하나의 try문 내에 여러 개의 예외가 발생 가능할 때 사용한다.
public class ExceptionMain03 {
	public static void main(String[] args) {
		int var = 50;
		//예외처리
		//다중 catch문
		//예외가 발생하면 예외객체가 전달되는 catch블럭으로 이동해서 수행문을 실행
		try {
			//			String -> int 변환
			int data = Integer.parseInt(args[0]);
			System.out.println(var/data);
			/*
			 * (주의) 다중 catch문을 사용할 때 Exception과 하위 예외클래스를
			 * 동시에 명시할 때 하위 예외 클래스를 먼저 명시하고 가장 뒤에
			 * Exception을 명시해야 동작상의 문제가 발생하지 않음
			 */
		}catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("입력한 데이터가 없습니다.");
		} catch(NumberFormatException e) {
			System.out.println("숫자가 아닙니다.");
		} catch(ArithmeticException e) {
			System.out.println("0으로 나눌 수 없습니다.");
		}
		
		System.out.println("프로그램 종료!");
	}

}

 

멀티 catch문

  • 멀티 catch문을 사용하면 하나의 catch문에 여러 개의 예외를 처리할 수 도 있다.
public class ExceptionMain04 {
	public static void main(String[] args) {
		//멀티 catch
		//하나의 catch 블럭에서 여러 개의 예외를 처리할 수 있도록
		// 예상되는 예외클래스를 여러 개 명시하는 방식
		
		try {
			int value1 = Integer.parseInt(args[0]);
			int value2 = Integer.parseInt(args[1]);
			int result = value1 + value2;
			System.out.println(value1 + "+" + value2 + "="+result);
		}catch(ArrayIndexOutOfBoundsException | NumberFormatException e) {
//			System.out.println("실행 매개값의 수가 부족하거나 숫자를 변환할 수 없습니다.");
			//예외 정보 제공
//			System.out.println(e.toString());
			e.printStackTrace();
			if(e instanceof ArrayIndexOutOfBoundsException) {
				System.out.println("실행 매개값의 수가 부족합니다.");
			}else if(e instanceof NumberFormatException) {
				System.out.println("숫자를 변환할 수 없습니다.");
			}
		}catch(Exception e) {
			System.out.println("알 수 없는 예외 발생");
		}
	}
}

 

throws 예약어

  • 예외를 처리하기 보다는 발생한 예외 객체를 양도하는 것이다. 즉, 현재 메서드에서 예외처리를 하기가 조금 어려운 상태일 때 현재 영역을 호출해준 곳으로 발생한 예외 객체를 대신 처리해 달라며 양도 하는 것이다. 사용법은 throws라는 예약어를 통해 메서드를 선언하는 것이다.
public class ExceptionMain06 {
	/*
	 * throws 예약어의 사용
	 * 메서드에 throws 예외클래스를 명시하면 메서드내에 try~catch블럭을
	 * 생략하고 예외가 발생하면 예외를 임시 보관하고 메서드를 호출하는 곳에
	 * try~catch블럭이 있을 경우 그곳으로 예외를 양도함
	 */
	public void printData() throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		System.out.print("단 입력");
		int dan = Integer.parseInt(br.readLine()); //한 라인에 입력한 데이터를 반환
		System.out.println(dan+"단");
		System.out.println("-------------------");
		for(int i=1; i<10 ; i++) {
			System.out.println(dan+"*"+i+"="+dan*i);
		}
		
	}
	public static void main(String[] args) {
		ExceptionMain06 em = new ExceptionMain06();
		try {
			em.printData();
		} catch(IOException e) {
			System.out.println("입력시 오류 발생");
		} catch(NumberFormatException e) {
			System.out.println("숫자가 아닙니다.");
		}
	}
}

 

throw 예외의 인위적인 발생

  • 사용자(프로그래머)가 의도적으로 예외를 발생시킬 때 throw문을 사용해 인위적으로 예외를 발생시킨다.
public class ExceptionMain07 {
	public void methodA(String[] n) throws Exception{
		if(n.length>0) { //데이터 입력 o
			for(String s: n) {
				System.out.println(s);
			}
		} else { //데이터 입력 x
			//예외를 인위적으로 발생시킴
			throw new Exception("배열에 요소가 없습니다.");
		}
	}
	public static void main(String[] args) {
		ExceptionMain07 em = new ExceptionMain07();
		try {
			em.methodA(args);
		} catch(Exception e) {
			System.out.println(e.toString());
			System.out.println(e.getMessage());
		}
	}

}

 

finally의 필요성

  • 예외가 발생하든 발행하지 않든 무조건 수행하는 부분이 바로 finally영역이다. 이것은 뒤에서 Database처리나 File처리를 한다면 꼭 필요한 부분이다. 이유는 Database를 열었다거나 또는 File을 열었다면 꼭 닫아주고 프로그램이 종료되어야 하기 때문이다.
public class ExceptionMain05 {
	
	public static void main(String[] args) {
		//try~catch~finally
		//finally 영역은 예외가 발생하든 발생하지 않든
		//무조건 수행하는 부분
		System.out.println("===예외가 발생하지 않는 경우===");
		try {
			System.out.println("1");
			System.out.println(10/0);
			System.out.println("2");
		}catch(Exception e) {
			System.out.println("3");
		}finally {
			System.out.println("4");
		}
	}
}

 

사용자 정의 예외

  • 사용자 정의 Exception이 필요한 이유는 표준예외가 발생할 때 예외에 대한 정보를 변경하거나 정보를 수정하고자 한다면 사용자가 직접 작성하여 보안된 예외를 발생시켜 원하는 결과를 얻는데 있다.
//사용자 정의 예외클래스
class NegativeNumberUseException extends Exception{
	public NegativeNumberUseException(String str) {
		super(str);
	}
}

public class ExceptionMain08 {
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.print("0이상만 입력");
		
		try {
			int n = sc.nextInt();
			if(n<0) {
				// 사용자 정의 예외 클래스에 예외 문구를 저장해서
				// 객체로 생성해서 예외를 발생시킴
				throw new NegativeNumberUseException("0이상만 입력해주세요.");
			} else {
				System.out.println("입력한 숫자 : " + n);
			}
		}catch(NegativeNumberUseException e) {
			System.out.println("예외 발생");
			System.out.println(e.toString());
		}finally {
			if(sc!=null) {
				sc.close();
			}
		}
	}
}

'IT 국비 교육' 카테고리의 다른 글

쌍용교육센터 - 15일  (1) 2024.03.08
쌍용교육센터 - 14일  (2) 2024.03.07
쌍용교육센터 - 12일  (0) 2024.03.05
쌍용교육센터 - 11일  (0) 2024.03.04
쌍용교육센터 - 10일  (0) 2024.02.29