Wanna be Brilliant Full-Stack Developer
자바 예외처리( 컴파일, 런타임) 본문
이번 시간에는 자바의 예외처리에 대해 알아보자!
예외처리를 한다고 해서 예외를 Exception라고 한다.
그래서 Exception처리가 무엇인지에대해서 먼저 생각해보자!
먼저 우리가 슈퍼마켓을 운영한다고 해보자! 애를 운영하기 위해서 사업을 시작할것이다.
슈퍼마켓 사업을 시작하기 전에 슈퍼마켓에서 일어날 수 있는 어떤 위험한 일에 대해서 생각해보는것이다.
첫번쨰로 슈퍼마켓을 운영하게 되면 도둑들이 있을 수 있기 떄문에 내가 미리 CCTV를 설치 할 수 있다.
그리고 슈퍼마켓을 운영하게 되면 잔돈이 5만원짜리를 내면 잔돈이 부족할 수 있기때문에 잔돈을 많이 준비해야한다.
그리고 직원도 채용을 해야한다.
그리고 장소도 임대를 해야한다. 이런 일들을 슈퍼마켓 운영되기 직전에 먼저 할 수 있다.
그런데 슈퍼마켓을 운여하기전에 내가 무엇을 했는가? CCTV를 설치하고 잔돈이 모자를 수 있으니까 잔돈을 준비하고
직원이 모자를 수 있으니 직원을 채용하고, 장소를 임대할 수 있는데 이런것들을 미리 처리 할 수 있다.
운영이 실제로 시작이 되면 내가 생각지 못했던 일들이 발생할 수 있다.
천원짜리 잔돈은을 준비헀는데 내가 생각했던것보다 훨씬더 잔돈이 필요할 수도 있다.
CCTV의 사각지대가 노출이 되어서 이거때문에 추가적으로 설치를 해야 할수도 있다.
내가 직원을 채용했는데 장사가 안되어서 직원을 줄여야 할 수도 있다.
그리고 장소를 임대했는데 이 장소가 어떤 이유때문에 장소를 변경해야 할 수도 있다.
그러면 여기서 말하는 이 두가지를 생각해봐야한다.
운영시작 되고 나서와 운영 전이다.
운영 전에 있는 예외들은요 컴파일시에 잡을 수 있다.
운영이 일어나고 나서 난 예외들은 런타임시에 잡아야한다.
실행후에 잡아야한다는것이다.
예외를 처리하는 방법은 컴파일시에 예외를 잡는 방법과
런타임시에 예외를 잡는 방법 2가지가 있다.
그래서 코드로 확인을 가져보는 시간을 가져보자!
컴파일시에 일어날 수있는 예외의 대표적인것이 무엇인가? 스레드 슬립이다.
Unhandled exception이라고 해서 너 이거 예외를 처리하지 않으면 애초에 컴파일 자체가 안된다는 것이다.
이런것들을 어떻게 처리하는가?
컴파일시에 처리를 해줘야한다.
마우스 올려서 Surround with try/catch라고 해서 잡아주면 된다.
여기보면 InterruptedException이라고 뜬다.
도대체 이게 먼지 잠깐 설명을 해보자
Thread.sleep이라는게 무엇인가? 우리가 지금 쓰고 있는게 메인스레드이다.
메인스레드가 1초동안 잠을 잔다는것이다.
이떄 발생할 수 있는 예외가 InterruptedException 어떤 방해가 일어날 수 있다는 것이다.
이게 무슨말인가?
자 내가 수업을 교실에서 하고 있다.
막 강의를 하고 있는데 근데 갑자기 문이 열리고 외부에서 누가 들어와서 밖에 화재가 발생했어요라고 이야기 하면서 들어온다. 그러면 어떻게 하는가? 화재가 발생했다고 헀으니까 지금 내가 하고 있는 일은 강의 의지만
그게 주된목적인데 화재가 발생헀으니 강의를 계쏙 이어가는것이 의미가 없다.
그래서 이떄는 예외처리를 하는것이 필요하다.
강의를 하다가 잠깐 나가서 화재를 진압하고, 119에 신고를 하든 그런 처리를 하고 다시 들어와서 강의를 하는것이다.
그래서 이런 처리하는 부분을 예외처리라고 한다!
예외처리를 하지 않으면 밖에 화재가 발생했으니까 계속 강의를 하다가 큰일이 난다.
Thread.sleep도 마찬가지이다. CPU가 일을 하다가 1초 잠을 잔다.
자고 있는 도중에 어떤 0.3초 정도 잤는 그 진행 시점에 인터럽트 방해가 발생이 될 수 있는데
갑자기 윈도우의 치명적인 오류가 발생하거나, OS쪽에 오류가 발생했을떄
그러면 치명적인 오류가 발생 방해가 들어오면 CPU까 잠을 자다가 잠깐 꺠서 0.3 초 자다가 0.7초 못자고
다시 잠깐 돌아와서 이 치명적인 오류를 처리하고 돌아와야 된다.
이런일이 발생할 수 있기떄문에 컴파일시에 미연에 방지하는것이다!
에를 실행하고 1초를 쉬었다가 어떤 메시지가 나올것이다.
그리고 Catch부분에 e.printStackTrace라고 적혀있는데 이건 중요하지 않고
실행을 하게 되면 잠자기 시작이 나오고나서 3초 지나고나서 잠자기 끝이 뜨는걸 볼 수 있다.
정상적으로 실행이되었다 왜냐하면 방해를 받지 않았기 때문이다.
그러면 대표적인 런타임 예외를 보자면?
배열을 하나 만들어보자!
배열은 3건의 데이터가 있는데 내가 Sysout해서 num의 3번지가 없는데
애를 실행하면 오류가 난다.
오류가 터지면 어떻게 되는가? 그 밑에 코드를 하나 적어보자!
이 메시지가 콘솔에 뜨지 않는다. 왜냐하면 여기 프로그램이 치명적인 오류 떄문에 더이상 진행 되지않고
그 위에서 강제 종료되기 때문이다.
프로그램이 이런식으로 강제로 종료가 되면 밑에 있는 코드가 실행되지 않는데
이런거를 내가 예외 처리를 해줘야한다.
애는 빨간줄이 안그어져 있다. 자바 입장에서는 저 배열이 오류인지 알 수가 없기 떄문이다.
그건 나만 아는것이다. 런타임 예외는 개발자가 알 수 있고
컴파일 예외는 JVM이 알 수 있다는것이다.
그래서 자바가 알 수 있으니까 예외 처리를 하지 않으면 오류가 저렇게 난다.
그래서 이렇게 오류가 나면 try catch로 묶게 되면 없는 애들은 전부다 컴파일 예외이다.
오류가 안나는데 실행할떄 오류가나는것을 런타임 예외라고 한다.
이것도 마찬가지로 TRY CATCH로 잡아야한다.
ArrayIndexOutOfBoundsException이라고 되어있는데 애를 복사해두고
Catch로 어떤 익셉션을 잡을꺼냐면 ArrayIndexOutOfBoundsException을 애를 잡을 것이고
저 런타임 예외 코드를 try 시도를 해봐서 만약에 시도를 하다가 ArrayIndexOutOfBoundsException 오류가 터지면
Catch로온다. CATCH의 역할은 무엇인가? TRY하다가(시도하다가) 예외가 발생하면 어떻게 처리 할지를
정의하는 영역이다.
즉 프로그램을 강제 종료시키지 않고 어떻게 처리를 할지 적어주는 것이다.
이렇게 런타임 예외를 잡아놔야지 프로그램이 강제 종료가 되지 않는다.
실제 서비스에서 TRY CATCH가 굉장히 중요하다!
트라이 캐치 하지 않으면 수많은 오류가 발생시킬 수 있고 그런 오류를 잡지 못했을 경우
프로그램이 예상치 못하게 종료 될수 있기 떄문에 우리가 제대로된 서비스를 할 수가 없다.
그런데 이렇게 괜찮아 그냥 진행해 라고 메시지만 찍는것이 아니라 어떤 오류가 있는지 확인해보는것이 좋다.
어떻게 하는가하면 sysout해서
여기에서주는 e라는 변수를 e.getMessage()라고 하면 어떤 오류가 발생했는지 정확히 알 수 있다.
Index 3는 길이를 벗어났다라는 말이다. 3개밖에 없기 떄문에 3번지를 잡고 있다는 것이다.
3개 있다는 것은 0번,1번,2번까지 있는것인데!
그리고 이것만으로느 먼가 부족하면 e.printStackTrace()가 있는데?
e.printStackTrace()가 무엇인가? 오류를 추적시켜준다.
오류의 추적 로그가 정확히 찍히게 된다.
그러면 지금은 오류가 저거만 찍혔지만 애떄문에 관련된 추가적인 오류가 나중에 다 찍힌다.
지금은 printStackTrace와 e.getMessage를 기억해두자!
나중에는 이런것들을 어떻게 하는가? 로그 파일들로 남겨야한다 혹은 데이터베이스에 저장하든지!
그렇게 해야지 개발자가 나중에 어떤 오류가 발생한것을 개발자가 확인을 할 수 있다.
아 이런 오류가 발생했구나 라고 생각 하게 되고 나중에 이런부분을 어떻게 해야할지 로그를 남겨두면 미리 알 수가 있다.
다음에는 이런 오류가 발생되지 않도록 처리를 해야한다.
그러면 하나만 더해보자!
String data = null; 이렇게 하면 data가 null이니까 값이 없는 Null이라는 값이 들어가면
null이라는 메시지가 뜬다. 내가 만약에 애를 초기화하지 않으면 컴파일시에 오류가 난다.
초기화 하라고 나온다. 이상태에서 내가 안녕이라고 적혀있을떄는 String도 문자열을 저장할 수 있는 어떤 자료형인데
문자열을 저장하는 애도 클래스이기 때문에 메서드들을 내부에 들고 있다.
클래스는 행위를 들고 있는데?
data.length라고하면 길이가 나온다!
내가 null이라고 하면 data가 null이니까 길이가 안나온다. 그리고 또 Exception이 나온다.
어떤 익셉션이 발생하는가?
NullPointerException이 뜬다. Null이라는 애가 들고 있는 메서드를 쓸수가 없다는 것이다.
length라는 메서드를 보면
static이 안붙어 있다. data가 null이라는것은 data가 메모리에 안떳다는 것이니까
length를 쓸수가 없다.
이렇게 하면 어려울 수 있기 떄문에!?
다른방법으로 만들어보자!
애는 static이 안붙어 있으니까 메모리에 안뜰것이다.
총이라는 애 객체를 만들고 정상적으로 만들어보자!
실행이 잘된다!
그러면 이부분에 내가 null이라고 하면 값이 안들어간다?
실행하면 NullPointerException이 뜬다.
null인데 그 포인터를 따라가봤더니 내가 Shoot이라는 메서드를 찾을수 없다는 것이다.
이것도 실행시에 나온것이기 떄문에 런타임 예외이다.
이런 예외가 발생할 수 있으니까 TRY CATCH로 묶는데
이렇게 묶어서 실행을 하면? 총이 없어서 발사하지 못했다 라고 뜬다.
그러면 여기서 보면 NullPointerException 인데 다른 익셉션을 넣으면 못잡는다.
그래서 스레드 종료가 안된다. 정확하게 잡아줘야한다!
이렇게 정확하게 잡는게 익셉션의 종류가 굉장히 많기 떄문에 다 이런것들을 기억해서 미리미리 적어놓기 힘들다.
그러면 컴파일예외같은것들은
컨트롤 해서 들어가면
위에 이렇게 부모가 Exception이다. 그래서
이렇게 변경해도 괜찮다. 부모의 메서드를 호출하면 자식의 메서들 호출하는 동적바인딩이 발생되고 오버라이드 무효화가 된다.
그리고 애도 마찬가지로 런타임 예외를 보면 부모가 있고
RuntimeException이 나온다. 부모로 다 잡아주면 다 잘 잡힌다.
그러면 런타임 예외는 RuntimeException으로 잡아주고
컴파일 예외는 Exception으로 잡아주면? 내가 예외를 처리하기가 굉장히 편해진다!
실제로 예외를 처리할때는 실제 총을 만들어줘야한다!
다시 만들어줘서 shoot을 하면
이런식으로 처리를 해줘야한다!
이게 예외 처리이다. 컴파일 예외가 있고 런타임 예외가 있다.
컴파일 예외는 코드를 적을떄 TOOL이 알아서 알려준다.
런타임 예외는 Tool이 알아서 알려줄수가 없다.
그래서 우리는 try catch로 묶어야한다
둘다 묶고 나서 어떤 exception을 적을수 힘들기 떄문에
일반적인 컴파일 예외는 exception이라고 적고
런타임 예외는 RuntimeException이라고 적어주면 편하게 처리 할 수 있다.
Catch는 try하다가 실패했으니까 후처리를 어떻게 해야하는지 적어주는 곳이다!!
'Some Memos > Java' 카테고리의 다른 글
자바 버퍼(Stream)이란? (0) | 2023.04.06 |
---|---|
자바 StringConstantPool 이란? (0) | 2023.04.04 |
자바 동기와 비동기가 무엇인가? (0) | 2023.03.28 |
자바 스레드 실습 해보자! (0) | 2023.03.21 |
자바 스레드 가 무엇인지 알아보자! (0) | 2023.03.20 |