Back to the Java

Exception 예외처리 / try-catch / throws / throw는 생성

Backcoder 2022. 7. 1. 19:50

< Exception > 예외

 

컴파일 오류, 시스템 오류, 등 많은 오류들 중에서 

자바 등, 프로그래밍으로 해결 가능 오류  <=   "예외" Exception 

 

예외 상황별로 =>  예외 클래스 이름붙여서 객체로 취급해준다. 

 

< 주요 Exception들 > 

Exception ( 조상님 )

RuntimeException ( 예외처리 안해줘도 되는 부류 )   
ArrayIndexOutofBoundsException ( 배열 인덱스 오류 )  
NumberFormatException ( "문자" 등, 숫자타입아닌 걸  Interger.parseint 하려할때 ) 
ArithmeticException 산술 오류 (100/0) 
IOException ( 입출력오류 조상격 )  
FileNotFoundException  ( 파일 못찾음 ) 

IllegalStateException   ( 메소드가 현재 동작할 상황을 충족시키지 못한 경우 )

IllegalArgumentException  ( 인자값 부적절 ) 

NullPointerException  ( 매개변수가 없음 ) 

 

 

 

자바는 "견고한 언어다" 

 

=> 예외 발생할 가능성이 있는 코드 => 미리 예측해서 예외 제거해놓는 방법을 쓴다. 

 

 

< 예외처리 2 / 생성 1 >  => try-catch / throws / throw 

 

1.  try  - catch          (직접처리) 

( 사실 상, 실제로 예외를 "직접" 처리하는 유일한 방법 )

   
 => try {   }영역 안에서,  예외가 발생하면  => catch 실행 

  (1) 예외가 발생할 가능성이 있는 코드블럭만 try { } 로 감싸준다. 

  (2) catch ( ~ Exception e(객체) ) {   a = 100; sout ( a / b );   } 
                                                                이런식으로 직접 고쳐줄 수 도 있고, 

                                                        { e . printStackTrace( ); }   오류 메세지를 날려줄 수도 있다. 

 

  (3) catch(  ArithmeticException e ){ ~ }        이 오류일 땐 이렇게 해 

       catch( IllegalArgumentException e){ ~ }  저 오류일 땐 저렇게 해줘 


    오류는 여러종류가 나올 수 있으므로, 종류별로 여러가지 catch를 걸어놓을 수 있다.

 

     catch ( Exception e ) { sout ( " 알수 없는 오류 입니다. " ) ; }       그것도 아니면 걍 나머지는  이거로 예외 때려줘 

   

  Exception 은 모든 예외들의 조상(Root) 이다. 

"마지막"에 Exception 으로 예외를 걸어두면, 예상해서 세팅해두지 못한 나머지 모든 Exception 들에 대해 

공통적으로 마지막 예외처리로 적용할 수 있다. 

                                                                      ( 마치 if 문에서 else 로 나머지 싹 처리하는 것 처럼 ) 

 

=> 이렇게 예외에 catch 를 해두면, 원래 발생해야 하는 예외대신 catch 가 실행되는 것 



 < finally > 
=> 예외발생이 되던 안되던     어쨋든 무조건 이거는 실행해주세요!

 

-  try {   } 중, 예외가 발생하면 바로 그 Line 부터 실행이 종료된다. 
   ( 그 Line 전 까지는 정상 실행 ) 

-  catch 를 실행한다. 

 

try { 1; 2; 3; 4; 5;  } 
catch (A ) { 6; } 
catch (B  ) { 7; } 
finally 8; 

 

3번에서 오류가 생겨 catch(A) 에서 잡았다면 

=> 1 - 2 - 6  - 8  

 

5번에서 오류가 생겨 catch(B) 에서 잡았다면 

=> 1 - 2 - 3 - 4 - 7 - 8 

 

Finally 는 보통은 마지막 부분에 쓰인다. 


  < 실무에선 >

try{
FileReader fr = new FileReader("a.txt"); 
while(true){ 
    if( fr.read( ) == -1 ) { break; }  }             //  -1이 파일의 끝을 의미 

catch ( IOException e ){ ... } 
finally { fr.close( ); } 

( 자바 등 프로그램에서파일을 가져와서 읽고 쓸 때, os 가 관리한다.

  하나의 파일을 동시에 여러 프로그램에서 사용할 수 없게 관리한다. 

 다 썻으면, 다 썻다고 .close ( ); 를 꼭! 해줘야 한다.  

 안닫아주면, os가 계속 대기함 - 버벅버벅  ) 
=> finally 로 무조건 실행하게 해주기!   

( 비슷한 이유로, DB 와의 연결도 반드시 끊어주기 위해 finally 를 사용한다

 

 

2.  throws   =>  간접처리  ( 예외 폭탄 던지기 ) 

 

Class A {

               메소드1       <= 예외 발생 

               메소드2( ) {  메소드1( ); }  

}

main ( ) { 메소드2( );  } 

 

메소드1 에서 예외가 발생하면 => 거기서 바로 try - catch 로 잡거나, 

 throws 로 메소드1 을 직접 사용할 놈에게 예외 폭탄을 넘길 수 있다. 

 

메소드1 : " 나 집중해야됨.  일단 만들어만 둘게. 예외는 니가 알아서 잡아서 써라. " 

메소드1( ) throws ~Exception{   } 

 

하필이면 메소드2 가 메소드1을 사용한다. 

메소드 2도 자기가 try-catch 로 잡을 수 있지만, 매우 귀찮은 상황 

 

메소드2 : " 나도 안할래 ~!  main 너도 이따가 메소드1 쓸거 다 안다. 니가해라. " 

메소드2( ) throws ~Exceptioin{   } 

 

그렇다. 메인은 메소드2를 써야해서, 결국 메소드1을 써야하는 처지다. 

 

결국 마지막에 누군가는 메소드1의 오류처리를 try -catch로 잡아줘야 한다. 

 

( main도  빡쳐서 throws 하면 자바인터프리터(자바실행툴) 가  기본 예외처리기능을 해주긴 한다. 

                      =>기본 e.printStackTrace( ) 기능 제공 ) 

 


=>  던져야할 예외 여러개 일 때 

메소드(  )throws AExcetpion, BException {   }       콤마로 여러개 던지기 가능   

 

 

 

< RuntimeException >

근데 예외처리를 하다보면, 처리를 안해줬는데도 별 문제 없이 잘 돌아가는 경우가 있다. 

 

예외처리가 필수가 아닌 예외들이기 때문이다. 

 

예외처리가 필수인가 / 아닌가 하는 차이는 조상 탓이다. 

 

1. RuntimeException 이 조상이면 => 예외처리 안해도 된다.  

                                                      ( Unchecked Exception 이라고 부르기도 한다. )  

 

2. RuntimeException 의 자식이 아니면 => 예외처리가 필수적이다.  ( 안할 시 오류 발생 ) 

                                                      ( Checked Exception 이라고 부른다. )  



<    그냥   Exception       /     RuntimeException     > 
  Checked Exception      /   Unchecked Exception
       예외처리 필수                     선택사항             
     IO / FileNotFound          Arithmetic / ArrayIndex

 

 

 

예외 처리를 안해줘도 되는 Runtime Exception 들의 경우엔    

심지어 직접 예외를 throw 해서 만들었더라도, 예외처리를 안해줘도 된다.

( 즉 try catch, throws 등을 안해 줘도 된다. )  


//

3. throw  => 예외발생 시키기 (의도적) 
(" 조건문 " 과 같이 쓴다.) 

if ( i == -1) { throw new ArithmeticException( "오류 설명 메세지" );} 

 

                           new 를 잊지 말자. 


< throw / throws 비교 > 

 

 method(  ) throws ~Exception {   }                          => 예외 넘기기 


 if (  ){ throw new ~Exception ("메세지" ); }             => 예외 생성  

 

throw 에서 메세지를 만들어 놓으면, 

catch 할때 =>   catch( ~Exception e ) {  sout( e.getMessage(  ) ); } 

 

getMessage 를 통해, 메세지를 보낼 수 있다. 

 

 ( catch 에서 예외 메세지 출력 )

sout( e.toString )      => 대략적  

e.printStackTrace     => 자세하게 ( print 가 붙어있어서 자동출력 )

sout( e.getMessage)  => throw 등에서 메세지 입력해둔게 있다면, 입력해둔 메세지 출력