백엔드/JAVA

👉🏻 에러의 종류 및 에러 처리

두개의 문 2023. 5. 18. 14:32

 

 에러의 종류

① 실행 에러( 실행 시, 알고리즘이 잘못되어 나타나는 논리 에러 
                       => 실행을 해야 에러 여부를 확인할 수 있음 : Runtime Error )
② 컴파일 에러

 

 


두 수를 입력받아 나누기 연산 시, 0으로 나누게 되면 어떻게 될까?
package myexception;

import java.util.Scanner;

public class DivideExceptionApp {

	public static void main(String[] args) {
		// 두 개의 숫자를 입력함
		Scanner sc = new Scanner(System.in);
		System.out.print("첫번째 숫자를 입력해주세요 : ");
		int num1 = Integer.parseInt(sc.next());
		System.out.print("\n두번째 숫자를 입력해주세요 : ");
		int num2 = Integer.parseInt(sc.next());

		// 입력한 수로 나누기
		System.out.println("입력한 두 수의 나누기 결과 : " + ( num1 / num2 ));
	}

}

- 변수 num2에 0을 입력했을 때 나타나는 에러

→ ArithmeticException : 예외적인 산술조건이 발생 시 나타나는 에러

 

▷ 에러 해결 방법

1) 조건문 이용 -> num2 = 0일 때, 다시 입력하도록 설정
=> 이런 방식으로 프로그래머가 발생할 에러에 대해 직접 조건을 설정한다 해도 프로그램의 모든 에러를 이렇게 처리할 수는 없음

2) Try - Catch 구문을 이용해보자

    - 스캐너를 통해 숫자를 입력받지 말고, 직접 지정 후 에러 처리해보자

try {

} catch {

} catch {

} finally {

}

 

  try : 실행할 코드 작성 -> 범위를 적당히 잡는 것이 좋다.

         예외가 발생할 수 있는 부분 -> 예외 발생 즉시, catch구문으로 가서 해당 예외 처리함
       ( 일반적으로 변수 선언부는 제외시킴 )
// 방대한 양의 데이터 처리 시, 메모리 점유율을 낮추는 게 낫기 때문에
// try 구문 내에 지역변수로 처리하는 것도 괜찮음 ( 변수 사용 후, 메모리에서 소멸시키므로 )
// 경우에 따라 적절히 사용하자.
   catch : Exception 발생 시 실행할 코드 작성
   finally : 에러가 발생하던 하지 않던 무조건 실행되는 부분 -> 필수적인 부분 아님 

 

package myexception;

import java.util.Scanner;

public class DivideExceptionApp2 {

	public static void main(String[] args) {
		
		try {
			int num1 = 1000;
			int num2 = 0;
			divide(num1, num2);
		} catch ( Exception ex ) {
			System.out.println("예외가 발생했습니다.");
		} finally {
			System.out.println("나는 무조건 마지막에 실행됩니다.");
		}
	}

			// 2-1. 결과값없음 | 콘솔창에 나오는 것은 처리값
	private static void divide(int num1, int num2){
		System.out.printf("%d / %d = %d", num1, num2, (num1/num2));
	}
	 
}

1. divide( ) 메서드에 'static'를 붙이지 않을 경우, 나타나는 에러 

 Cannot make a static reference to the non-static method divide(int, int)  from the type DivideExceptionApp2

→ main( ) 메서드가 'static'이므로, divide( ) 메서드를 호출하기 위해서는 'static'를 붙여야 함

    ('static'를 붙이지 않을 경우, 인스턴스 메서드이므로 static메서드에서 호출 불가능 )

2. divide( ) 메서드의 결과값 없으므로 'void'로 처리

    ( 콘솔 창에 나오는 것은 결과값이 아닌 처리값 )

 

 

 


이번에는 args배열의 인수값 입력 받은 후 에러 처리

 

package myexception;

public class DivideExceptionApp3 {

	public static void main(String[] args) {
		try {
			int num1 = Integer.parseInt(args[0]);
			int num2 = Integer.parseInt(args[1]);
			
			divide(num1, num2);
			
		} catch (ArithmeticException ae) {
			// 3. 
			// ArithmeticException : 예외적인 산술조건이 발생 시 나타나는 에러
			// 이 에러가 어디서 나는지 알려줘야 함.. -> throws구문 사용
			// Unreachable catch block for ArithmeticException. 
			// It is already handled by the catch block for Exception
			// Ctrl + Shift + O 눌러도 해결 안됨
			
			System.out.println("두번째 숫자는 0이 아닌 수를 입력해주세요.");
		} catch (Exception ex) {
			// 모든 예외 상황의 부모
			System.out.println("예외가 발생했습니다. : " + ex);
		}

	}
    // 3-1. throws 구문을 사용하여 여기서 이런 예외(자바에서는 에러를 예외라 부름)가
	// 발생할지도 모르니 상위처리부분(함수호출)에서 대비해주세요 라고 통지하는 것
	//  - 사용방법 : 함수 선언부 throws 미리대비할예외타입 (함수 구현부);
	private static void divide ( int num1, int num2 )
									throws ArithmeticException{
		System.out.println("나눗셈 결과 : " + ( num1 / num2 ));
	}
}

// args는 프로그램 외부에서 프로그램을 실행할 때 넘겨주는 인수값의 배열입니다.

// 이렇게 넘어오는 인수값은 기본적으로 문자열입니다.

// 따라서 Integer.parseInt()로 문자열->정수로 변환처리합니다.

// 예)DivideExceptionApp3 1000 0

args배열의 인수값 입력 -> Run Configurations -> (x)=Arguments -> Program arguments에 1000 한칸 띄고 0 입력 후 Apply -> Run 누르면 됨

Show Command Line 클릭 시, 명령프롬프트 창에서 입력할 때의 command line 확인 할 수 있음
******* 디버그 해보자 *******

 

** catch 구문에는 순서 존재 ->  

맨 처음부터 exception(모든 예외)로 선언해 준다면, 두 번째, 세 번째... 선언한 catch 문은 수행할 수가 없습니다.

 

호출한 곳에서 처리해주겠다'라고 생각하시면 됩니다.

즉, 발생한 예외를 호출한 곳으로 넘겨주는 것이 throws입니다.

 

 


예외를 인위적으로 발생시켜보자 -throw 키워드 이용

 

// 자바시험 점수를 입력 시, 음수를 입력할 경우 -> 음수는 0점 처리

package myexception;

public class InvalidInputExceptionApp {

	public static void main(String[] args) {
		
		try {
		// 자바시험 점수를 입력 시, 음수를 입력할 경우
		// 음수는 0점 처리
		
		int javaScore = Integer.parseInt(args[0]);
		
		if(javaScore < 0) {
			//System.out.println("시험 점수는 음수를 입력할 수 없습니다.");
			throw new IllegalArgumentException();
            	// 원래 자바에 있는 클래스를 불러온 것..
		}
		
		System.out.println("입력한 자바점수 : " + javaScore);
		} catch (IllegalArgumentException e) {
			System.out.println("시험점수는 음수를 입력할 수 없습니다.");
		}
	}

}

 new 예와 명();를 하여 객체를 생성하여 <throw 객체>로 예외를 발생시킵니다. 
이렇게 발생한 예외는 알맞은 catch 문에 들어가 예외 처리를 할 수 있죠. throw는 사람이 '인위적'으로 발생시키는 예외입니다. 반드시 처리해줘야 할 예외를 명시적으로 예외를 발생시켜, 유지 보수에 도움을 주기도 합니다.

 

 


 

 

'백엔드 > JAVA' 카테고리의 다른 글

H2 데이터베이스 연결 (2)  (0) 2023.05.22
H2 데이터베이스 연결 (1)  (0) 2023.05.22
객체 지향 프로그래밍 이론(6)  (0) 2023.05.16
13일차 수업 기록  (0) 2023.05.15
객체 지향 프로그래밍 이론(4)  (0) 2023.05.12