예외처리(Exception handling)방법

by 조쉬 posted Sep 21, 2016
?

단축키

Prev이전 문서

Next다음 문서

ESC닫기

크게 작게 위로 아래로 댓글로 가기 인쇄

< 예외처리(Exception handling)방법 >


1. try/catch 예외처리


2. RuntimeException은 "미확인 예외"


3. 예외 회피하기 "throws"  /  예외 강제발생 "throw"


4. 사용자정의 예외





예외 처리란 무엇인가? 또는 왜 써야 하는지?


컴파일러를 통해 컴파일을 성공적으로 수행하여 *.class 파일이 생성된 후 실행을 할 수 있다. 컴파일이 성공적으로 수행이 되었다 하여 프로그램(*.class)의 실행 시에도 에러가 발생하지 않는 것이 아니다.

컴파일러는 실행 도중에 발생할 수 있는 잠재적인 오류까지는 검사를 하지 않기 때문이다. 실행 도중 에러가 나서 프로그램이 멈춰버린 상태로 계속 유지되거나 갑자기 종료되는  경우 등이 이에 해당한다.

개발자는 이런 예외적인 상황을 대비하기 위해 예외 처리를 사용하는 것 이다.

예외처리를 통해 개발자가 적절한 코드를 작성하여 프로그램의 비정상적인 상태를 막을 수 있다.







1. try / catch 예외처리.



try{ 

       // 예외가 발생 할 것 같은 것을 안에 넣어 주면 된다.

}catch(Exception e){

 // try{} 블럭 안에서 예외(Exception)가 발생할경우 이 문제를 처리할 코드 작성

}






try / catch 미적용 했을 때 ]


// 0으로 나눌때 발생하는 예외 


public class MyException {

public static void main(String[] args){

int num=100;

int result=0;

for(int i=0;i<10; i++){

result= num/(int)(Math.random()*10);   // (num / 0)일때 ArithmeticException 예외발생 

System.out.println(result);                

}

}

}


[실행결과]

50

16

Exception in thread "main" java.lang.ArithmeticException: / by zero

at test.MyException.main(MyException.java:10)



[ try / catch 적용 했을때 ]


// 0으로 나눌때 발생하는 예외


public class MyException {

public static void main(String[] args){

int num=100;

int result=0;

for(int i=0;i<10; i++){

     try{

result= num/(int)(Math.random()*10);     // (num / 0)일때 ArithmeticException 예외발생

System.out.println(result);

     }catch(ArithmeticException  ae){

System.out.println("0");

     }

}

}

}


[실행결과]

16

16

50

25

16

0    <- catch에서 실행이 되어 출력.   ArithmeticException발생

14

20

11

16









2. RuntimeException은 "미확인 예외"


아래 사진은 예외 클래스의 계층구조를 나타낸다. Exception 은 Throwable를 상속받고 Throwable은 Object를 상속 받는다.






Exception클래스만 따로 살펴 보겠다.




Exception을 두 부류로 나눌 수 있다. 

1. Exception 클래스와 Exception 클래스를 상속을 받은 나머지 클래스들 (단, RuntimeException 부류는 제외 )

2. RuntimeException 클래스와 RuntimeException을 상속받은 클래스들



RuntimeException은 미확인 예외 "라고 말하였다.

궁금증이 생겨야 한다. 왜 Exception을 두부류로 나누었고 미확인 예외가 무엇인지.



두부류로 나눈 중요한 차이점은 컴파일시의 예외 처리 체크를 하느냐 안 하느냐의 차이다.

컴파일러는 RuntimeException을 제외한 모든 Exception 클래스들을 컴파일시 예외처리( try / catch )를 했는지 반드시 확인 한다. 만약 예외 처리( try / catch )를 하지 않으면 컴파일 시에 에러가 발생한다.


한마디로 컴파일러는 2. RuntimeException 클래스 부류가 발생했을 때 ( try / catch )를 사용하지 않더라도 컴파일까지는 가능하다는 것이고  2. RuntimeException클래스 부류를 제외한 모든 Exception 클래스는 ( try / catch )를 확인한다는 것이다.



간단한 소스로 정말 그런지 확인을 하겠다.


RuntimeException 클래스 부류]


// try/catch문을 사용하지 않아도 되는 RuntimeException 클래스 이다.


public class MyException {

public static void main(String[] args){

throw new RuntimeException();    // ( try / catch )를 생략했으나 컴파일시 문제가 없다 직접해봐라.

}

}


[실행결과]

Exception in thread "main" java.lang.RuntimeException

at test.MyException.main(MyException.java:5)


//실행시에는 대체해줄 예외처리를 작성하지 않았기에 실행에서 문제가 발생한 것이다.




Exception클래스 부류 ]


// try/catch문을 꼭 작성해줘야하는 Exception클래스 이다.

// 예외처리를 해주어 실행이 되지만, try / catch를 지우면 컴파일에서 문제가 발생한다.


public class MyException {

public static void main(String[] args){

try{

throw new Exception();  // Exception 강제발생

}catch(Exception e){

System.out.println("Exception 발생");

}

}

}


[실행결과]

Exception 발생



이렇게 두가지 분류로 나뉘며 컴파일러가 확인유무로 판별이 가능하다 

그런데 왜?  RuntimeException은 ( try / catch )가 사용되었는지 확인을 하지 않을가?  그이유는 RuntimeException에 속하는 클래스들은 주로 개발자의 실수에 의해 발생되는 예외들이 많다.  예를 들어 ArithmeticException(0으로 나누기) , IndexOutOfBoundsException(배열범위) 등이 있다. 이런 것들은 개발자가 조금만 더 신경쓰면 예외가 발생하지 않게끔 해줄수 있기에 컴파일러가 확인하지 않게 되었다라고 볼수도 있다(정확한 이유는 java만든 사람에게 문의를..)

그렇다면 Exception클래스 부류는 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외이다. FileNotFoundException은 존재하지 않는 파일의 이름을 사용자가 입력할때 발생 한다.


정확히 내가 찾는 예외클래스가 두가지 부류중 어디에 속하는지 알고 싶을땐 API문서를 참고하면 된다. 간단히 찾을수 있다.


상속 계층을 살펴봤을 때 Exception 클래스 아래로 RuntimeException이 있다면 두 번째 부류이고, 없다면 Exception 부류이다. 간단하게 생각하면 된다.









3. 예외 회피하기 "throws"  /  예외 강제발생 "throw"


"예외 강제 발생 throw" 바로 위에서 사용했으니 먼저 살펴보겠다.

throw라는 키워드는 고의로 예외를 발생시키겠다는 것이다.


[ throw 예외 강제발생 ]


public class MyException {

public static void main(String[] args){

try{

Exception e=new Exception();

throw e;                               //예외 강제발생

// throw new Exception();  //예외 강제발생

}catch(Exception e){                //발생된 new Exception(); 이 catch에 잡힌다.

System.out.println("Exception 발생");  

}

}

}



예외 회피하기 "throws"는 메서드에 예외를 선언하기 위해 사용되는 키워드로 

서 예외를 회피, 떠넘기기 라고 보면 된다.