지금까지 예외처리를 하기위해서 사용했던 것으로는 조건문(if, switch)등을 통해서 예외를 처리했습니다. 이러한 조건을 통한 예외 말고도 예외라는 말은 다른 뜻으로 사용합니다.

 

그것은 사용자(개발자)의 잘못된 조작이나 잘못된 코딩으로 인해 발생하는 프로그램 오류를 예외(exception)라고 사용합니다.

 

그렇다면 지금까지 사용했던 예외 처리인 if 문을 잠깐 보고 추가 적인 예외 문들을 보도록 하겠습니다.

 

● if문을 이용한 예외처리

 

- 나눗셈

package 예외처리;
import java.util.Scanner;
public class 예외처리{
	public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
	 	
		System.out.print("피제수 입력 : "); 
		int num1 = input.nextInt();
		
		System.out.println("제수 입력 : ");
		int num2 = input.nextInt();
		
		if(num2 ==0) { // 예외처리 & 기능의 조건 체크 
			System.out.println("0으로 나눌 수 없습니다.");
			return;
		}
	}
}

이것이 지금까지 우리가 사용해 온 예외의 처리방식입니다. if 문이 프로그램의 주 흐름인지, 아니면 예외의 처리인지 구분이 되지 않는다는 단점이 있습니다.

 

● try ~ catch 문

 

위의 같은 예제를 통해서 try ~ catch 문을 보여드리겠습니다.

 

- try : 예외발생의 감지 대상을 감싸는 목적으로 사용합니다. (예외발생 가능 지역 확인)

- catch : 발생한 예외상황의 처리를 위한 목적으로 사용합니다. (예외처리 코드 확인)

package 예외처리;
import java.util.Scanner;
public class 예외처리 {
	public static void main(String[] args) {
		
        System.out.println("두 개의 정수를 입력 : ");
		Scanner input = new Scanner(System.in);
		
		int num1 = input.nextInt();
		int num2 = input.nextInt();
		
		// 예외나 error 처리하는 명령어- try{}catch(){}
		
		// ArithmeticException
		try {
			System.out.println(num1/num2);
		}catch(ArithmeticException e){ 0으로 나누었을 때, ArithmeticException발생하는 예외.
			System.out.println("0으로 나눌 수 없습니다.");
		}
		System.out.println("프로그램 종료...");
	}
}

 num1/num2 연산이 될 때 num2 의 값이 0이 들어오게되면 :

catch로 가서 ArithmeticException의 예외가 발생하여 System.out.println("0으로 나눌 수 없습니다."); 값을 출력합니다.

여기서  ArithmeticException 0으로 나누었을 때 console 에서 나타나는 error와 함께 나타나는 예외 문구 입니다.

 

try ~ catch 의 특징 중 하나는 try문 내에서 예외상황이 발생하고 처리된 다음에는, 나머지 try문을 건너뛰고, try~catch의 이후를 실행합니다. java가 적절하게 블록을 구성해줍니다.

 

 ○ e.getMessage( ) , catch 여러개 사용 가능

getMessage : 메소드는 예외가 발생한 원인정보를 문자열의 형태로 반환해줍니다.

catch는 예외의 한개 외에도 있을 수 있을 때, 여러개를 사용할 수 있다. 

 

package 예외처리;
import java.util.Scanner;
public class ExceptionOtherTryCatch {
	public static void main(String[] args) {
		
		Scanner input = new Scanner(System.in);
		int[] arr = new int[5]; 
		for(int i = 0; i <2 ; i++)
			
		try {
			System.out.println("피제수 입력: ");
			int num1 = input.nextInt();
			
			System.out.println("제수 이력: ");
			int num2 = input.nextInt();
			
			System.out.print("연산 결과를 저장할 배열의 인덱스(0~4) 입력 : ");
			int index = input.nextInt();
			
			arr[index] =  num1 / num2;
			
		// 예외가 나눗셈 이외의 것도 있을 수 있을 때, 여러개를 사용할 수 있다. 
		}catch(ArithmeticException e) {
			System.out.println(e.getMessage());
			System.out.println("0으로 나눌 수 없습니다.");
		}catch(ArrayIndexOutOfBoundsException e) {
			System.out.println(e.getMessage());
			System.out.println("배열의 인덱스 접근 에러 발생.");
		}

ArithmeticException 의 ArithmeticExceptione.getMessage() / by zero가 출력 됩니다.

 

이 외에도 java가 정의 하고 있는 예외처리

// ArrayIndexOutOfBoundsException
try {
int[] arr = new int[3];
arr[-1] =20; // index 값은 0부터 시작. // ArrayIndexOutOfBoundsException 배열의 범위를 넘어설때 나타나는 예외
}catch(ArrayIndexOutOfBoundsException e) {
System.out.println(e.getMessage()); // getMessage : java 가 사용하는 오류 메세지 출력
System.out.println("배열의 범위를 벗어남."); 
}	
			
				
// ClassCastException
try {
Object obj = new int[10];  // 모든 자료형은 java가 Object를 상속하는 구조로 만들어주기 때문에 
// 다형성에 관계에 의해서 자식의 자료형을 부모의 자료형으로 바라 볼 수 있으므로 문제 없다.
String Str = (String) obj;    // int 형을 String으로 잘못된 강제 형변환에 의한 error 발생 
}catch(ClassCastException e) { // ClassCastException: 강제형변환 예외.
System.out.println(e.getMessage()); // getMessage : java 가 사용하는 오류 메세지 출력
System.out.println("int 형을 String으로 잘못된 강제 형변환에 의한 error 발생 "); 
}

// NegativeArraySizeException
try {
Object obj = new int[-10]; 
}catch(NegativeArraySizeException e) { 
System.out.println(e.getMessage()); // getMessage : java 가 사용하는 오류 메세지 출력 //
} // null 출력 , 모든 결과가 메세지로 나오지 않는다. 
				
				
// NullPointerException
try {
String name = null;
int length = name.length(); 
// NullPointerException : 참조자료형에 new 의해서 주소값을 담아주지 않고 
   method를 생성하기 때문에 발생. 주소값이 담겨 있지 않는 null 값이다. // name 값이 null
}catch(NullPointerException e) {  
System.out.println(e.getMessage());
}

 

 

java는 문법적으로나 수학적으로 문제가 일어났을 때에만 예외처리 할 수 있습니다. 그렇다면 문법적으로는 문제는 없지만 논리적으로나 물리적으로 문제가 되는 경우는 ex) 나이 값을 음수로 넣었다면?? 어떻게 해야할까요?

이러한 문제점을 해결하기 위해서 프로그래머 스스로 예외상황이 발생했을 때 처리하도록 문법 구문을 제공합니다.

 

<사용자 정의 예외 처리 자료문>

class AgeInputException extends Exception{ //Exception 예외처리 기능 
	AgeInputException(){
		
		super("유효하지 않은 나이를 입력하셨습니다."); 
	}
}

public class ProgrammerDefineException {

	public static void main(String[] args) {
		System.out.println("나이를 입력하세요 : ");

		int age;
		try {
			age = -20;
			System.out.println("당신의 나이는 : " +  age + " 살 이군요.");
			
		} catch (AgeInputException e) {
			System.out.println(e.getMessage()); 
		}
	}
	

위와 같이 나이의 값에 음수를 넣게 되면 catch로 넘어가서 사용자가 정의한 class로 가서 supe()의 값을 출력합니다.

결과값 : "유효하지 않은 나이를 입력하셨습니다."  가 출력됩니다.

 

○ throw

 

public class ProgrammerDefineException {
	public static void main(String[] args) {
		System.out.println("나이를 입력하세요 : ");

		int age;
		try {
			age = readAge();
			System.out.println("당신의 나이는 : " +  age + " 살 이군요.");
			
		} catch (AgeInputException e) {
			//e.printStackTrace(); // printStackTrace() 의 기능 : 예외가 발생했을 때 메세지를 출력해준다. 
			System.out.println(e.getMessage()); 
		}
	}
	 public static int readAge() throws AgeInputException{ 
   -- throws AgeInputException 실행과정에서 예외가 발생할 수 있는 method 임을 명시하는 것입니다. 
		 Scanner input = new Scanner(System.in);              
   -- throws AgeInputException 가 있는 method 를 받을 때는 try catch 문으로 받아야합니다.
		 int age = input.nextInt();
		 
		 if(age < 0) 
			 AgeInputException except =  new AgeInputException(); 
			 throw except; 
   -- throws catch 문을 찾겠다. throw가 제공 되는 method가 
      나타나면 try , catch 문으로 받아야한다.
		 } 
		 return age;  
	 }
}

throw : 예외의 상황을 던져버린다. 그리고 return을 받는 main method 에서 try ~ catch 문으로 받았다.

예외가 처리되지 않고 넘어감을 명시해야 하며, 예외인스턴스의 참조변수를 기반으로 구성을 합니다.

 

+ Recent posts