예외처리
프로그램 에러
프로그램이 실행중 오작동하거나 비정상적으로 종료되는 경우를 발생시점에 따라 세가지로 분류할 수 있습니다.
1. 컴파일 에러 : 컴파일시 발생하는 에러
컴파일에러는 우리가 프로그램을 실행할때 소스코드를 컴파일하게 되고 오타나 자료형 등등을 체크하고 오류가
없는지 체크를 한 뒤 오류가 없다면 .class파일을 생성하게 됩니다.
2. 런타임 에러 : 실행 시에 발생하는 에러
아래에 후술하겠습니다.
3. 논리적 에러 : 실행은 되지만, 의도와 다르게 동작하는 것
int a = 8;
int b = 4;
int c = a + b / 2;
// 우리가 원하는 c의 결과값 : 6;
// 실제 실행시 c의 결과값 : 10;
논리적 에러는 컴파일과 실행은 정상적으로 진행되지만 사실 99%의 경우라면
우리는 원하는 결과값인 6을 얻기 위해 위와 같이 코드를 짜고 a + b에 괄호를 쳤겠지만
사용자의 실수로 괄호가 빠져서 결과값이 달라졌다하더라도 컴퓨터는 정상적으로 작동을 해서 결과값을 내려줍니다.
이러한 경우를 논리적 에러라고 합니다.
런타임 에러
그렇다면 런타임에러란 무엇일까요?
컴파일 에러에도 걸리지 않았고 논리적 에러에도 걸리지 않았지만 프로그램이 실행중에 에러가 발생할 수 있습니다.
자바에서는 실행 시 발생할 수 있는 프로그램 오류를 Throwable이라는 클래스 아래에서
두가지로 분류하고 있습니다.
에러(error)와 예외처리(Exception)인데
에러란 프로그램 코드에 의해 수습될 수 없는 심각한 오류
예외처리란 프로그램 코드에 수습될 수 있는 다소 미약한 오류라고 표현하고 있습니다
그렇다면 둘다 오류인건 알겠고 왜 나누었을까? 정도의 차이라면은 대체 어느정도의
정도의 차이길래 나눴을까라는 궁금증이 생깁니다
에러의 예
코딩테스트 사이트의 경우 문제별로 메모리 제한과 스택의 제한이 설정되어 있는데
많은 횟수의 재귀함수를 돌리거나 많은 변수를 선언하게 되면 메모리를 초과하는 상황이 발생하게 되고
이때 StackOverflowError가 발생하게 됩니다.
이러한 경우는 우리가 지금까지 공부했던 예외처리로 처리할 수 있는 영역이 아니기 때문에
이는 에러로 분류됩니다.
예외처리
이러한 예외처리는 아래와 같이 다시 크게 두가지로 나눌 수 있습니다.
RuntimeException과 그 외의 Exception으로 나눌 수가 있는데
RuntimeException은
주로 프로그래밍과 관계가 깊은 예외로 배열의 범위를 벗어난다던지 형변환을 잘못했다던지 등의 경우의 예외처리 방식입니다.
런타임 에러를 발생시킵니다.
그리고 나머지 Exception은
사용자에 의한 에러로 존재하지 않는 파일의 이름을 입력한다던지 클래스 이름을 잘못적는 등의 예외처리 방식입니다.
이러한 RuntimeException을 제외한 Exception들은 컴파일 에러를 발생시킨다는 특징을 가지고 있습니다.
https://freestyle385.tistory.com/12
JAVA Exception 종류
출처: https://silverbullet.tistory.com/entry/Exception의-종류와-발생원인 [경제적 자유를 위한 여정 기록] ClassNotFoundException 클래스를 찾지 못함 CloneNotSupportedException Cloneable 인터페이스 미구현 IllegalAccessExce
freestyle385.tistory.com
우리는 보통 RuntimeException에 대한 내용을 예외처리를 합니다.
그렇다면 예외처리란,
프로그램 실행시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것이며
프로그램의 비정상 종료를 막고 정상적인 실행 상태를 유지하는 행위입니다.
try - catch문
예외를 처리하기 위해서는 try - catch문을 사용합니다.
try - catch문의 구조로는
try {
//예외가 발생될만한 코드
} catch(FileNotFoundException e){ //FileNotFoundException이 발생했다면
} catch(IOException e){ //IOException이 발생했다면
} catch(Exception e){ //Exception이 발생했다면
} finally {
///어떤 예외가 발생하던 말던 무조건 실행
}
이와 같은 형태를 가질 수 있고 catch문은 여러번 반복 할 수있습니다.
catch문은 위에서 아래로 순차적으로 검사를 하므로 작은 단위의 예외처리부터 진행을 해야 합니다.
만약 위와 같이 IOException보다 더 상위의 클래스인 Exception을 먼저 선언을 한다면 이는 컴파일 에러에 해당합니다.
또한 catch에 들어 있는 예외처리를 담을 구문이 try에 없다면 위사진과 같이 역시 컴파일 에러를 발생시킵니다.
Throw
또한 try - catch문을 통해 예외처리를 하는 것이 아니고 Throw를 사용해 고의로 예외를 발생시키는 경우도 가능합니다.
Exception e = new Exception("고의로 발생시킴")
throw e;
// 결과 값 : 고의로 발생시킴
throw new Exception("고의로 발생시킴")
// 위의 코드로 간략하게 선언할 수 있다.
// 결과 값 : 고의로 발생시킴
throw와 try - catch문의 차이라고 하면은
throw는 예외를 던지는 것이라고 표현을 할 수가 있고
try - catch문은 예외를 받아서 처리하는 것이라고 할 수 있습니다.
이 말이 무슨 뜻이냐 하면은
try - catch문은 try에서 예외가 발생하고 catch에서 그 예외를 받아서 예외처리를 처리해준다고 하면
throw는 바로 예외를 던져주는 것 즉 try에서도 예외를 발생시켜서 catch로 던져줄 수 있습니다.
try {
throw new Exception("고의로 발생시킴");
} catch(Exception e) {
System.out.println(e.getMessage());
}
// 결과값 : 고의로 발생시킴
// getMessage()를 통해 예외클래스 인스턴스의 저장된 메세지를 얻을 수 있습니다.