Published 2022. 11. 7. 17:22

*에러 종류 
 -시스템 에러 : 컴퓨터의 오작동으로 발생하는 에러 -> 소스코드로 해결안됨-> 심각한 에러
 -컴파일 에러 : 소스코드 문법상의 오류 -> 빨간줄로 오류 알려줌 (개발자의 실수) -> 소스코드 수정으로 해결
 -런타임 에러 : 코드 상으로는 문제가 없지만 프로그램 실행 중 발생하는 에러 (사용자의 실수 or 개발자가 예측가능한 경우를 제대로 처리안했을경우)  ->소스코드 수정으로 해결가능 
 -논리 에러 : 문법적으로도 문제없고, 실행했을 때도 굳이 문제는 없지만 프로그램 의도상 맞지 않는 것들 
 
 * 시스템 에러를 제외한 컴파일,런타임, 논리 에러와 같은 덜 심각한 것들을 "예외"라고 표현함 == Exception
 * 이런 "예외"가 "발생"했을 경우에 대해 처리하는 방법을 "예외처리" 라고 함 
 
  *예외처리를 하는 목적
 -예외처리를 하지 않고 그대로 예외가 발생되는 경우 프로그램이 비정상적으로 종료됨
 
  *예외처리 방법
 * 1.try~catch문을 이용
   try{
       예외가 발생될 수 있는 구문;
   } catch(발생될 예외클래스 매개변수){
      해당 예외가 발생됐을 경우 실행할 구문 미리작성; 
   }
 * 2.throws를 이용
  메소드명() throws IOException {
   }

1️⃣ UnCheckedException
 - RuntimeException : 프로그램 실행시 주로 발생하는 예외들(런타임 에러)

RuntimeException의 후손들
 * - IndexOutOfBoundsException : 부적절한 인덱스 제시시 발생되는 예외
 * - NullPointerException : 레퍼런스가 null로 초기화된 상태에서 어딘가에 접근할때 발생되는 예외
 * - ClassCastException : 허용할 수 없는 형변환이 진행될때 발생되는 예외 
 * - ArithmeticException : 나누기 연산시 0으로 나눠질때 발생되는 예외
 * - NegativeArraySizeException : 배열 할당시 배열의 크기를 음수로 지정하는 경우 발생되는 예외
 *  ...
 *  => RuntimeException 관련된 예외들은 충분히 "예측가능"함 
 *     애초에 예외자체가 발생이 안되도록 조건문으로 해결가능 (예외처리 아님)

//ArithmeticException  예시 

public void method1() {
		//ArithmeticException 
		//사용자에게 두수를 입력받아 두수의 나눗셈 연산
		System.out.print("정수 1: ");
		int num1 = sc.nextInt();
		
		System.out.print("정수 2: ");
		int num2 = sc.nextInt();
        int result = num1 / num2; //-> 정수2에 0을 입력시 ArithmeticException 발생
		//-> 프로그램 비정상적으로 종료됨

 

문제 해결방법 1. if 문 사용 하여 예외가 발생하지 않도록 조건검사 => 예외처리 아님 

public void method1() {
		System.out.print("정수 1: ");
		int num1 = sc.nextInt();
		
		System.out.print("정수 2: ");
		int num2 = sc.nextInt();
    
	    int result = 0;
		 if(num2 != 0) {
			result = num1 / num2;
		}
		System.out.println("안녕하세요, 반갑습니다. 당신의 결과를 알려드리겠습니다.");
		System.out.println("result: "+ result);


 문제 해결방법 2.  예외처리 구문 작성 (try~catch 구문)

public void method1() {
		System.out.print("정수 1: ");
		int num1 = sc.nextInt();
		
		System.out.print("정수 2: ");
		int num2 = sc.nextInt();
		try {
			int result = num1 / num2;
			System.out.println("result : " + result);
					
		} catch (ArithmeticException e) {
			System.out.println("0으로 나눌 수 없습니다.");
		// e.printStackTrace(); // 현재 예외발생된 이력 강제로 보고자할 때 (비정상적 종료 아님)
		}
		System.out.println("프로그램을 종료합니다.");
	}

//NegativeArraySizeException / ArrayIndexOutOfBoundsException 예시 

public void method2() {
		System.out.print("배열의 크기 : ");
		int size = sc.nextInt();
		
		int[] arr = new int[size];
		//배열의 크기 음수로 입력시 NegativeArraySizeException 발생 (배열의 크기는 양수여야함)
	
		System.out.println("100번 인덱스 값 : " + arr[100]);
		//arr[100](100번 index)보다 작은 수 입력 시 ArrayIndexOutOfBoundsException 발생

문제 해결방법 1.  if 문 사용 하여 예외가 발생하지 않도록 조건검사 => 예외처리 아님 

public void method2() {
		System.out.print("배열의 크기 : ");
		int size = sc.nextInt();
        
		if(size>0) {
			int[] arr = new int[size];
			
			if(size > 100) {
				System.out.println("100번 인덱스 값 : "+ arr[100]);
			}
		}

문제 해결방법 2. 예외처리 구문 작성 (try~catch 구문)

public void method2() {
		System.out.print("배열의 크기 : ");
		int size = sc.nextInt();
        
        try {
			int[] arr = new int[size];
			System.out.println("100번 인덱스 값 : " + arr[100] );
		} catch(NegativeArraySizeException e) {
			System.out.println("배열의 크기는 음수로 제시할 수 없습니다.");
		} catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("부적절한 인덱스로 접근할 수 없습니다.");
		}
		// 다중 catch블럭 작성 가능 
	
		System.out.println("프로그램을 종료합니다. ");
	}

//InputMismatchException 예시 
:위의 예시에서 size값에 int형을 입력하지 않았을때 발생하는 예외 

해결방법1.  try~catch구문 추가 

	public void method3() {
		System.out.print("배열의 크기 : ");
	
    try {
			int size = sc.nextInt(); // size값에 int 형을 넣지않았을때 발생하는 예외 
			int[] arr = new int[size];
			System.out.println("100번 인덱스 값 : " + arr[100] );
		} catch(NegativeArraySizeException e) {
			System.out.println("배열의 크기는 음수로 제시할 수 없습니다.");
		} catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("부적절한 인덱스로 접근할 수 없습니다.");
		} catch(InputMismatchException e){ //java.until 패키지에 있기때문에 import필요 
		    System.out.println("정수만을 입력해야합니다.");
		}

해결방법 2.  다형성 적용하여  catch구문에 RuntimeException 클래스 적용 
          단 , 부모클래스와 자식 클래스를 가지고 catch구문 작성시 자식클래스 catch블럭이 부모클래스보다 위에있어야 함 

public void method3() {
	
		System.out.print("배열의 크기 : ");
		try {
			int size = sc.nextInt();
			int[] arr = new int[size];
			System.out.println("100번 인덱스 값 : " + arr[100] );
			
		} catch(NegativeArraySizeException e ) {// 순서중요 **부모와 자식예외클래스를 같이 작성시에는 자식예외클래스가 위에작성되어야함
			System.out.println("음수가 아닌 양수로 배열의 크기를 지정해야합니다. ");
				
		} catch(RuntimeException e) {//다형성 적용해서 부모타임의 예외클래스 작성가능, 모든 자식 예외 발생시 다 받아서 처리 할 수 있음
			System.out.println("예외가 발생됐어..;; 배열의 크기가 잘못됐거나, 부적절한 인덱스 제시했거나, 정수가 아닌값을 입력했을거야" );
            
		}
        //부모예외클래스와 자식예외클래스를 가지고 catch블럭을 기술할 경우
		//자식 예외클래스 catch블럭이 부모보다 위에 있어야함 
			
		System.out.println("프로그램을 종료합니다. ");
		}

 

*정리 

 RuntimeException 관련 예외들은 예외 처리 구문이 필수는 아니기 때문에 UncheckedException
 * if문(조건문) : 애초에 예외자체가 발생되기 전에 소스코드로 핸들링 (예외처리 구문 아님)
 * try ~ catch문 : 예외가 "발생됐을경우" 실행할 구문을 미리 작성해두는 것 (예외처리 구문)
 *  예측가능한 상황은 if문과 같은 조건문으로 해결하는 것이 권장사항임
   

'JAVA' 카테고리의 다른 글

12. IO (IntputOutput) _ file생성  (0) 2022.11.07
11.Exception_ CheckedException  (0) 2022.11.07
10. API _ Date  (0) 2022.11.04
10. API _ Wrapper  (0) 2022.11.04
10. API _ StringTokenizer  (0) 2022.11.04
복사했습니다!