- 컴파일 에러 : 컴파일 시에 발생하는 에러
- 런타임 에러 : 실행 시에 발생하는 에러
- 논리적 에러 : 실행은 되지만, 의도와 다르게 동작하는 것
컴파일 에러
- 개발 환경에서 대부분 원인 발견
- 오타, 잘못된 구문, 자료형 체크 등
- 오류가 수정되어야 프로그램이 정상 실행됨
런타임 에러
1) Error 에러
- JVM 에서 발생
- 메모리 부족, 스택오버플로우처럼 일단 발생하면 복구 불가 -> 프로그램에서 제어 불가
2) 예외 (Exception 클래스)
체크 (checked) 예외
- 컴파일러가 예외처리를 확인
- 예외를 잡아서 처리하거나, 던지거나 둘 중 하나를 필수로 선택
- 예외를 던지려면 throws 선언 필수
언체크 (Unchecked) 예외
- 컴파일러가 예외처리를 확인 X
- RuntimeException 과 그 자식 예외는 모두 언체크 예외
런타임 예외라고 많이 부름
- 예외를 잡거나, 던지지 않아도 됨
- 예외를 잡지 않으면 자동으로 상위로 넘어감
예외 처리
프로그램의 비정상 종료 방지
try-catch
try {
예외발생가능성
} catch(Exception e) {
예외처리
} finally {
무조건 실행
}
throws 선언 추가 (예외 처리 미루기)
: 예외를 해당 메서드에서 처리하지 않고 미룬 후 메서드를 호출하여 사용하는 부분에서 예외 처리
- 미뤄진 곳에서 또 미루기
- main( ) 에서 throws 👉 JVM 으로 보내짐 👉 대부분 프로그램 비정상 종료
- 웹 애플리케이션의 경우 여러 사용자의 요청을 처리하기 때문에 시스템이 종료되면 안 됨. WAS가 해당 예외를 받아 처리 -> 주로 개발자가 지정한 오류 페이지를 사용자에게 보여줌
- 미뤄진 곳에서 처리
main( ) 에서 try-catch
다중 예외 처리
try {
} catch() {
} catch() {
} catch(Exception e) {
}
- 반드시 예외 처리해야 하는 경우 이외에도 모든 예외 상황을 처리하고자 할 때
- 맨 마지막에 Exception 클래스로 처리
사용자 정의 예외
사용자 정의 예외 클래스
class 예외클래스명 extends Exception {
예외클래스명(String Message) { //생성자
super(Message);
}
}
예외 발생시키기
throw new 예외클래스명("Message");
체크 예외 활용
- 기본적으로 언체크 예외 사용
- 체크 예외는 비즈니스 로직상 의도적으로 던지는 예외에만 사용
- ex) 계좌 이체 실패 예외, 로그인 IP, PW 불일치 예외..
체크 예외의 문제
- 복구 불가능한 예외임에도 컨트롤러나 서비스는 계속 예외를 선언해야 한다
- 의존 관계 문제 : 기술이 변경될 때마다 예외도 변경해야 한다
- 여러 예외 발생시 결국 최상위 타입인 Exception을 던질 수도 있는데, 그렇게 되면 다른 체크 예외 기능이 무효화되고 중요한 체크 예외를 놓치게 되는 문제
언체크 예외 활용
- 컨트롤러나 서비스가 예외를 처리할 수 없다면 예외 선언 부분을 생략 가능
throws~
- 따라서 의존 관계 문제가 발생하지 않음
- 중간에 구현 기술이 변경되어도 코드 컨트롤러, 서비스에서 변경할 필요 X
예외를 공통으로 처리하는 한 곳만 변경하면 됨
문서화
- 런타임 예외는 문서화가 중요
- 또는 코드에
throws 런타임예외
를 남겨 중요한 예외임을 인지