Exception 예외처리 / try-catch / throws / throw는 생성
< 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 등에서 메세지 입력해둔게 있다면, 입력해둔 메세지 출력