JAVA_20_예외

hyeong taek jo·2023년 7월 11일

JAVA

목록 보기
20/39

📌예외란오류(Error) vs 예외(Exception)

  • 오류(Error)는 시스템 비정상적인 상황이 생겼을 때 발생한다. 이는 시스템 레벨에서 발생하기 때문에 심각한 수준의 오류이다. 따라서 개발자가 미리 예측하여 처리할 수도 없기에 오류에 대한 처리는 신경쓰지 않는다.
    ex. 수학에서는 0으로 나눌 수 없기 때문에 발생하는 오류

  • 예외(Exception)는 오류와 반대로, 비정상적인 상황이 예측하여 처리하는 것이다. 개발자는 자신이 구현한 로직에서 예외를 예측하고 그에 따른 예외처리를 신경써야 한다.

오류(Error) vs 예외(Exception)

  • 오류(Error)는 시스템 비정상적인 상황이 생겼을 때 발생한다. 이는 시스템 레벨에서 발생하기 때문에 심각한 수준의 오류이다. 따라서 개발자가 미리 예측하여 처리할 수도 없기에 오류에 대한 처리는 신경쓰지 않는다.

  • ex. 수학에서는 0으로 나눌 수 없기 때문에 발생하는 오류

  • 예외(Exception)는 오류와 반대로, 비정상적인 상황이 예측하여 처리하는 것이다. 개발자는 자신이 구현한 로직에서 예외를 예측하고 그에 따른 예외처리를 신경써야 한다.

📌Exception 처리

-처리하는 방법에는 여러가지가 있겠는데 어떤 에러가 발생할지 알고 있다면 Excepiton클래스명을 직접 명시해주거나 아니면 Excepiton을 통해 한꺼번에 처리해주는 방법도 있다.
그리고
자바 예외처리방법 3가지를 잘 쓰면 된다.

) try-catch (finally) - 다른 작업 흐름으로 유도
2) throws - 호출한 쪽(부모)에게 예외 처리 위임하도록
3) throw - 명확한 의미의 예외로 바로 처리 ==> 개발자들이 비즈니스 로직에서 처리하는 방식임!

📌throws

hrows는 자신을 호출하는 메소드에 예외처리의 책임을 떠넘기는 것이다.

기본적으로 체크 예외 전략이다.
언체크(런타임)예외는 체크예외와 다르게 throws 예외 선언을 하지 않아도 된다.
예외를 잡지 않아도 자연스럽게 상위로 넘어가기 때문이다.
코드를 보며 정리해보자면,

public class ThrowTest {

    public static void main(String[] args) {

        int n1, n2;

        n1=12;
        n2=0;

        try {
            throwTest(n1, n2);
        } catch (ArithmeticException e) {
            // n1/n2 라면 발생했을 것
            System.out.println("ArithmeticException: " + e.getMessage());
        }
    }

    public static void throwTest(int a, int b) throws ArithmeticException{
        System.out.println("throw a/b: "+ a/b);
    }
}

메소드 뒤에 throws ArithmeticException 부분이 보일 것이다. ArithmeticException 예외가 발생하면

<이 메소드를 호출한곳(main메서드)에서 예외처리를 넘겨주라는 뜻이다.

그래서 예외처리를 넘겨받은 main메서드는 어떻게 처리할까?

반드시 try-catch구문으로 메서드호출부분을 감싸줘야 한다.
그렇지 않으면 예외처리를 하는 구문이 없으면 오류처리를 아무도 안하게 되는 것이다! throws를 쓰면 그 호출한 메서드에서 try-catch 구문을 해줘야되는 것을 잊으면 안된다!

📌throw

  • throw는 throws랑 확연히 다르다. 제일 헷갈렸던 부분이었는데,
    throw는 개발자가 직접 예외를 발생시키고싶을 때 쓰는 것이다.
    RuntimeException(UnCheckedException) 처리를 위해 쓰는 방식이다.
    Spring 프레임워크를 쓸 때 ExceptionHandler 와 찰떡궁합인 방식이다.
    이것도 코드를 보면서 이해해보자.
public class ThrowTest {

    public static void main(String[] args) {

        int n1, n2;

        n1=12;
        n2=0;

        try {
            throwTest(n1, n2);
        } catch (ArithmeticException e) {
            // n1/n2 라면 발생했을 것
            System.out.println("ArithmeticException: " + e.getMessage());
        }
    }

    public static void throwTest(int a, int b) throws ArithmeticException{
        throw new ArithmeticException();
    }
}

위에 throws 구문 코드에서 예외 발생 메서드 throwTest 구문 안에 throw new ArithmeticException();을 넣어주는 것을 확인할 수 있다.

이런식으로 사용자가 직접 예외를 발생시켜주고싶은 부분에 throw new XXXExcepiton();을 통하여 예외를 발생시켜주고 throws를 통하여 예외처리를 던져주는 것이다.

그러면 main에서 throwExample 메소드를 호출할때 예외처리를 해줄 것이다.
하지만 결과 를 보면 뭔가 이상하다.

바로 main문에서 예외처리를 해준 메시지 처리가 null로 나오기 때문이다.

throw는 Exception을 던질 때 예외 내용도 던져주지 않는다.

그래서 개발자가 직접 Exception을 따로 커스터마이징해서 만들고 그 안에 메시지를 넣어서 던져주는 방식이다.

throw는 개발자가 직접 예외를 발생시키고싶을 때 쓰는 것이지만 추가적으로 Exception 재정의해서 사용한다.

예외를 처리하는 방법은 두 가지

1) 예외가 발생된 메소드 내에서 처리하는 방법(try, catch 절 사용)

  • try 블록은 예외가 발생할 가능성이 있는 범위를 지정하는 블록이다. try 블록은 최소한 하나의 catch 블록이 있어야 하며, catch 블록은 try 블록 다음에 위치한다.

  • 지정된 타입의 예외 객체가 발생하면 try 블록의 나머지 문장들은 수행되지 않고, 자바가상 머신은 발생한 예외 객체를 발생시키며 발생한 예외 객체 타입이 동일한 catch 블록을 수행한다.

  • finally 블록은 필수 블록은 아니다.
    finally 블록이 사용되면 finally 블록의 내용은 예외 발생 유무나 예외 catch 유무와 상관없이 무조건 수행. 따라서, 데이터베이스나 파일을 사용한 후 닫는 기능과 같이 항상 수행해야 할 필요가 있는 경우에 사용한다

- 예시 -

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Exception3 {

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		
		while(true) {
			int num;
			int i = 0;
			try {
				i ++;
				if(i > 3) break;
				System.out.println();
				// 출력 후 라인 바뀌지 않음
				System.out.print("첫 번째 값을 입력하세요 --> ");
				int num1 = Integer.parseInt(in.readLine());
				// 만일 a를 넣었다고 가정하면 문자열을 숫자로 못바꾸니까 오류가 발생함
				                           //readLine을 쓰면 main의 IOException을
				                           // 무조건 써줘야 한다.
				System.out.print("두 번째 값을 입력하세요 --> ");
				int num2 = Integer.parseInt(in.readLine());
				// 출력후 라인 바꿈
				
				System.out.println(num1 + " / " + num2 + " = " + num1/num2);
				
			} catch (NumberFormatException e) {
				System.out.println("숫자를 입력해야 합니다..");
			} catch (ArithmeticException e) {
				System.out.println("0으로 나누면 안되요" );
			} catch (Exception e) { 
				System.out.println("값을 잘못 입력했습니다.." + e.getMessage());
			}
			// NumberFormatException, ArithmeticException의 오류가 안걸리면
			// 마지막에 exception에서 오류를 잡는다.
			// 마지막은 항상 Exception써주는게 좋다.
		}
	}
}

2) 예외가 발생된 메소드를 호출한 메소드에게 예외의 처리를 넘겨주는 방법 (throws 절 사용)

  • 예외(Exception)이 발생한 메소드를 호출 한 곳으로 예외 객체를 넘기는 방법

- 예시 -

public class ExceptionEx03 {

	public static void main(String[] args) {
		try {
			method1();
		} catch (Exception e) {
			System.out.println("main메서드에서 예외가 처리");
		}
	}
	
	static void method1() throws Exception {
		try {
			throw new Exception ();
		} catch (Exception e) {
			System.out.println("method1메서드에서 예외가 처리");
			throw e; //  다시 예외를 발생시킨다.
		}
	}
}

method1메서드에서 예외가 처리
main메서드에서 예외가 처리

  • 기존의 예외 클래스로 예외를 처리할 수 없다면 사용자만의 예외 클래스를 작성하여 발생시킬 수 있다. 사용자가 예외 클래스를 정의하려면 예외 클래스의 최상위 클래스인 java.lang.Exception 클래스를 상속받아 클래스를 정의한다.
    ex) class 예외 클래스 이름 extends Exception

- 예시 -

import java.util.Scanner;

public class MyExceptionEx {

	public static void main(String[] args) {
		int kkk = 0;
		// 1. 객체선언
		Scanner sc = new Scanner(System.in);
		System.out.println("원하는 숫자 입력?");
		try {
			kkk = sc.nextInt();
			if(kkk > 10 ) throw new MyException();
		} catch (MyException e) {
			System.out.println("MyException--> "+ e.getMessage());
		} catch (Exception e) {
			System.out.println("Exception --> " + e.getMessage());
		}
		System.out.println("kkk->"+kkk);
	}
}

public class MyException extends Exception {
	@Override
	public String getMessage() {
		//return super.getMessage();
		// 기본적으로 설정되어 있지만 내가 아래처럼 정의 가능
		String myErrMsg;
		// 10보다 크다니
		myErrMsg = "아니 10보다 크다니";
		
		return myErrMsg;
	}
}

원하는 숫자 입력?
45
MyException--> 아니 10보다 크다니
kkk->45

profile
마포구 주민

0개의 댓글