Language/Java

예외처리

kalza 2018. 9. 4. 09:50

예외는 프로그램에 문제가 있는 것을 말한다.

예외로 인해 시스템 동작이 멈출때 이를 대비하여 막는것을 예외처리라고 한다.

우선 예외처리 방법을 알아보기전에 에러와 예외의 차이를 간단히 살펴보고자 한다.



출처

https://stackoverflow.com/users/51681/georgios-gousios

https://stackoverflow.com/questions/912334/differences-between-exception-and-error/912352


위 그림처럼 에러는 시스템 단에서 발생하며 개발자가 대처 할 수 없다.

예외는 잘못된 입력, 연산, 시스템과부하, 하드워드 또는 네트워크 문제발생의 예상지점에서 대처가 가능하다.




예외에도 2가지 종류가 있는데 Checked ExceptionUnchecked Exception이 있다.


· Checked Exception :

반드시 처리해야하는 경우며(네트워크, 파일 시스템등) 처리하지 않을경우 컴파일 되지 않는다.

대표적으로 IOException, SQLException 등이 있다.


· Unchecked Exception : 

개발자의 판단에 맡기는 경우다.(데이터 오류 등)

대표적으로 NullPointerException, IndexOutOfBoundsException 등이 있다.




예외 클래스로 Exception 클래스가 있는데, Exception 클래스의 하위 클래스로는 여러 클래스들이 존재한다.

이제, 예외처리를 위한 문법을 알아본다.


try{


예외가 발생할 수 있는 코드


}catch (Exception e){


예외가 발생했을때 처리할 코드


}finally{


예외 발생과 상관없이 무조건 실행되는 코드

}



아래 코드는 정수 10을 0으로 나누었을때 (10/0) 발생하는 예외를 처리하는 코드다.



 public static void main(String[] args) {

int i = 10;

int j = 0;

int r = 0;

System.out.println("Exception BEFORE");

try {

r = i / j;                                    

}catch(Exception e) {

e.printStackTrace();

System.out.println("Exception : " + e.getMessage());

}

System.out.println("Exception AFTER");

 }


catch절 안에 printStackTrace 메서드는 스택에 에러가 발생된 메서드의 호출 기록을 남겨 출력해준다.

getMessage 메서드는 오류의 원인만을 리턴하는 메서드다.


이번엔 ArrayList타입 변수에 null을 대입하여 레퍼런스가 존재하지 않았을때 변수를 사용하면

발생될 예외에 대한 처리를 해보고, 배열을 선언하여 값을 초기화한후 배열의 인덱스 값을 고의적으로

벗어나 예외를 발생시켜 처리하는 코드를 작성해본다.


 public class MainClass002 {


public static void main(String[] args) {


Scanner sc = new Scanner(System.in);

int i, j;

ArrayList<String> list = null;

System.out.println(list);

int[] iArr = {0,1,2,3,4};


System.out.println("exception BEFORE");


try {

System.out.println("input i  : ");

i = sc.nextInt();

System.out.println("input j : ");

j = sc.nextInt();


System.out.println(" i / j  = " + ( i / j ));                                                  -- ①


for (int k=0; k<6; k++) {                                                                     -- ②

System.out.println("iArr[" + k + "] : " + iArr[k]);

}

System.out.println("list.size () : " + list.size());                                            -- ③

}catch(InputMismatchException e) {                                                                  -- ④

e.printStackTrace();

}catch(ArrayIndexOutOfBoundsException e) {                                                   -- ⑤

e.printStackTrace();

}catch(Exception e) {                                                                                  -- ⑥                  

e.printStackTrace();    

}

System.out.println("Exception AFTER");                                                           -- ⑦

sc.close();


}

 }


① : 첫번째 입력값에 두번째 입력값으로 나눈 결과를 화면에 출력한다.

     두번째 입력값에 0을 입력하게 되면 java.lang.ArithmeticException: / by zero 에러를 발생하게 되고

     이에 대한 처리는 ⑥의 catch절에서 예외 처리 한다. 

     정수가 아닌 값을 입력할 경우 ④의 catch절에서 예외 처리 한다.

② : 배열 iArr에 담긴 인덱스는 총 5개며, 0,1,2,34가 들어가있다. 조건식 k<6은 인덱스의 범위를 넘어섰기때문에

⑤의 catch절에서 예외 처리 한다.

③ : list에는 null이 담겨져있고 참고할 레퍼런스가 존재하지 않으므로 size 메서드를 사용 할 수 없고 NullPointerException이

    발생하지만 NullPointerException에 대한 처리를 따로 하지 않았으므로 부모인 Exception 예외처리가 되어있는

    ⑥의 catch절에서 예외 처리한다.


위와 같이 예외 처리가 이루어지면, try-catch 구문을 벗어나 다음 코드인 ⑦을 수행한다.

만약, 예외처리를 하지 않으면 다음 코드로 진행 되지 않고 중단된다.