예외처리

김민성·2022년 7월 14일
0

Java

목록 보기
21/47
post-thumbnail

예외처리

  • 프로그램의 오류

    • 컴파일 에러 : 컴파일 시에 발생하는 에러

      System.out.println("자바")

      위의 코드처럼 뒤에 ; 을 붙이지 않으면 나타나는 에러가 대표적인 컴파일 에러이다.

    • 런타임 에러 : 실행 시에 발생하는 에러

      int[] arr = {1,2,3,4};
      System.out.println(arr[10]);

      위의 코드는 코드상에선 오류가 없지만 배열의 10번째 방이 없기 때문에 실행시에 에러가 발생하고 이러한 에러를 런타임 에러라고 한다.

    • 논리적 에러 : 실행은 되지만, 의도와 다르게 동작하는 것

      int[] arr = {1,2,3,4};
      System.out.println("first data : " + arr[1]);

      위의 코드는 컴파일 에러나 런타임 에러가 발생하지 않지만, 코드 작성자의 실수로 인해 의도한 first data를 배열의 두번째 값으로 출력했다. 이러한 에러를 논리적 에러라고 한다.

  • 예외처리 try ~ catch ~ finally 문

    • try ~ catch ~ finally 문의 구조

      try{

      ​ 예외가 발생할 수 있는 문장1

      ​ 예외가 발생할 수 있는 문장2

      ​ ...

      } catch(예외클래스명 객체명) {

      ​ 해당 예외 발생시 수행할 문장

      ​ ...

      ​ catch 블럭은 여러개 쓸 수 있다.

      } finally {

      ​ 예외 발생 유무에 상관없이 무조건 실행할 문장

      ​ finally 블럭은 생략 가능하다.

      }

    public class Main{
    	public static void main(String[] args) {
    		try {
    			Scanner sc = new Scanner(System.in);
    			System.out.print("아무 숫자나 입력하세요 : ");
    			int a = sc.nextInt();
    		} catch (Exception e) {
    			System.out.println("숫자만 입력해주세요.");
    		} finally {
    			System.out.println("프로그램 종료.");
    		}
    	}
    }

    위의 코드를 보자. try문 안에서 먼저 사용자에게 숫자값을 하나 입력받는다. 이 때 사용자는 숫자가 아닌 다른 값을 입력할 수 있기 때문에 그 경우에 대한 예외 처리를 해주어야 한다. 따라서 숫자가 아닌 다른 값을 입력하는 예외 발생시 catch문으로 들어가 "숫자만 입력해주세요"가 출력되는 것이다. 그리고 finally 문 안에 있는 것은 예외 가 발생 유무에 상관없이 무조건 실행한다.

    public class Main{
    	public static void main(String[] args) {
    		try {
    			Scanner sc = new Scanner(System.in);
    			System.out.print("0이 아닌 아무 숫자나 입력하세요 : ");
    			int a = sc.nextInt();
    			System.out.println(5/a);
    		} catch (ArithmeticException e) {
    			System.out.println("'0이 아닌' 숫자를 입력하세요.");
    		} catch (InputMismatchException e) {
    			System.out.println("0이 아닌 '숫자'을 입력해주세요");
    		}
    	}
    }

    위의 코드를 보자. 숫자값을 하나 입력받아 5를 그 숫자로 나눈 값을 출력하려고 한다. 이 때 생각할 수 있는 오류는 두 가지 이다. 첫 번째로 입력받은 숫자가 0이거나, 두 번째로 입력받은 값이 숫자가 아니거나 이다. 따라서 0으로 나누었을 때 발생하는 예외인 ArithmeticExceptionsc.nextINT()에 숫자가 아닌 다른 값을 입력했을 때 발생하는 예외인 InputMismatchException 클래스들을 이용해서 catch문을 두개 사용할 수 있다.

  • Exception 클래스

    • 모든 예외 클래스들의 부모클래스이다.
    public class Main{
    	public static void main(String[] args) {
    		try {
    			Scanner sc = new Scanner(System.in);
    			System.out.print("0이 아닌 아무 숫자나 입력하세요 : ");
    			int a = sc.nextInt();
    			System.out.println(5/a);
    		} catch (Exception e) {
    			System.out.println("0이 아닌 숫자를 입력하세요.");
    		}
    	}
    }

    위의 코드를 보자. 여기서도 생각해볼 수 있는 예외는 0을 넣었을 때와 숫자가 아닌 값을 넣을 때 두가지이다. 그때의 예외 클래스인 ArithmeticException 클래스와 InputMismatchException 클래스 모두 Exception 클래스를 상속받고있기 때문에 Exception 클래스 하나만을 써서 모든 예외를 잡아낼 수 있다.

    하지만 사용자의 입장에서, 발생할 수 있는 예외의 종류를 세분화해 각 케이스마다 적절한 설명을 출력해주는 것이 더 편하다. 따라서 생각해볼 수 있는 각각의 예외를 모두 잡아 적절한 설명문을 출력해준 후 마지막 catch 문에서 생각하지 못했던 예외를 잡기 위해 Exception 클래스를 써주는게 좋다.

  • 예외 발생시키기

    키워드 throw 를 사용해서 고의로 예외를 발생시킬 수 있다.

    public class Main{
    	public static void main(String[] args) {
    		try {
    			Exception e = new Exception("고의로 예외 발생.");
    			throw e;
    			// throw new Exception("고의로 예외 발생."); 한줄로도 가능
    		} catch (Exception e) {
    			System.out.println("에러가 발생했습니다 : " + e.getMessage());
    		}
    	}
    }
  • 메서드에 예외 선언하기

    throws 키워드를 사용하며, 메서드 선언부 내부에서 발생하는 예외를 무시하고 호출한 곳으로 해당 예외를 떠넘기게 된다. 따라서 호출한 곳에서는 try~catch 문으로 예외를 잡아줘야한다.

    public class Main{
    	public static void main(String[] args) {
    		try {
    			System.out.println(method(3));
    		} catch (Exception e) {
    			System.out.println("0으로 나눌 수 없습니다.");
    		}
    	}
    	
    	static int method(int x) throws Exception {
    		int a = 0;
    		return x/a;
    	}
    }

    위의 코드를 보자. method 메서드에서 매개변수 x를 받아와 a로 나눈다. 그런데 a의 값이 0으로 초기화 되어 있으므로 예외가 발생할 것이다. 따라서 throws Exception 으로 예외를 무시한다.

    그리고 main 메서드에서 method 메서드를 선언할 때 try~catch 문으로 발생하는 예외를 잡아준다.

0개의 댓글