Exception
과Error
를 구분해야 함
Exception
은 소스코드로 처리할 수 있는 예외 상황→ 계산기에서 0으로 나누는 상황을 예외 처리의 예시로 보여줌
error
는 아래 정의와 같음
프로그램 수행 시 치명적 상황이 발생하여 비정상 종료 상황이 발생한 것, 프로그램 에러라고도 함
컴파일 에러 : 프로그램의 실행을 막는 소스 코드상의 문법 에러. 소스 코드 수정으로 해결.
개발자가 실수한 것
int a = 99.9; (타입 불일치)
런타임 에러 : 프로그램 실행 중 발생하는 에러. 주로 if
문 사용으로 에러 처리
ex. 배열의 인덱스 범위를 벗어났거나, 계산식의 오류
시스템 에러 : 컴퓨터 오작동으로 인한 에러, 소스 코드 수정으로 해결 불가
시스템 에러 == 버그
- 서버 다운
- 연산 지연
- 부품 손상
- … 등 외부적 요인에 의한 시스템 오작동
소스 코드 수정으로 해결 가능한 에러를 예외(Exception)라고 하는데
이러한 예외 상황(예측 가능한 에러) 구문을 처리 하는 방법인 예외 처리를 통해 해결
Java API Document에서 해당 클래스에 대한 생성자나 메소드를 검색하면
그 메소드가 어떤 Exception을 발생시킬 가능성이 있는지 확인 가능.
→ 발생하는 예외를 미리 확인하여 상황에 따른 예외 처리 코드를 작성할 수 있음
Exception과 Error 클래스 모두 Object 클래스의 자손이며 모든 예외의 최고 조상은 Exception 클래스
반드시 예외 처리해야 하는 Checked Exception과 해주지 않아도 되는 Unchecked Exception으로 나뉨
빨간 줄 위가 Unchecked, 아래가 Checked
Unchecked
: 확인 굳이 안해도 되는 예외 (개발자가 선택적으로 예외 처리)
→ 코드 작성 시 빨간 줄이 뜨지 않는 것들Checked : 확인을 꼭 해야만 하는 예외 (예외 처리 필수)
Unchecked Exception으로 주로 프로그래머의 부주의로 인한 오류인 경우가 많기 때문에
예외 처리보다는 코드를 수정해야 하는 경우가 많음
ArithmeticException
0으로 나누는 경우 발생
if문으로 나누는 수가 0인지 검사
NullPointerException
Null인 참조 변수로 객체 멤버 참조 시도 시 발생
객체 사용 전에 참조 변수가 null인지 확인
NegativeArraySizeException
****배열 크기를 음수로 지정한 경우 발생
배열 크기를 0보다 크게 지정해야 함
ArrayIndexOutOfBoundsException
배열의 index범위를 넘어서 참조하는 경우
배열명.length를 사용하여 배열의 범위 확인
ClassCastException
Cast연산자 사용 시 타입 오류
instanceof 연산자로 객체타입 확인 후 cast연산
InputMismatchException
Scanner를 사용하여 데이터 입력 시
입력 받는 자료형이 불일치할 경우 발생
try
: 예외가 발생할 것 같은 코드 수행을 시도한다는 뜻⇒ 수행 중 예외 발생시, 예외 객체가 던져짐 (throw)
catch
(던진것을 받다) : try에서 던져진 예외를 잡아서 처리 → 예외를 잡아 처리했기 때문에 프로그램이 종료되지 않음
try~catch문을 이용하여 예외 처리
try
: Exception 발생할 가능성이 있는 코드를 안에 기술catch
: try 구문에서 Exception 발생 시 해당하는 Exception에 대한 처리 기술 여러 개의 Exception 처리가 가능하나 Exception간의 상속 관계 고려해야 함finally
: Exception 발생 여부와 관계없이 꼭 처리해야 하는 로직 기술 중간에 return
문을 만나도 finally구문은 실행되지만 System.exit();
를 만나면 무조건 프로그램 종료 주로 java.io나 java.sql 패키지의 메소드 처리 시 이용public void method() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("입력 : ");
String str = br.readLine();
System.out.println("입력된 문자열 : " + str);
} catch (IOException e) {
e.printStackTrace();
}
}
public void method() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("입력 : ");
String str = br.readLine();
System.out.println("입력된 문자열 : " + str);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
System.out.println("BufferedReader 반환");
br.close(); // 보통 close하는 경우 사용
} catch (IOException e) {
e.printStackTrace();
}
}
}
책임 전가의 느낌
에러가 여러 곳에서 발생하는 걸 굳이 매번 try - catch하지 않고
throws를 이용해 한곳에서 처리
메소드 선언 시 throws Exception명을 추가하여 호출한 상위 메소드에게 처리 위임
계속 위임하면 main() 메소드까지 위임하게 되고
main()
메소드에서도 처리되지 않는 경우 프로그램이 비정상 종료됨.
오버라이딩: 상속받은 메서드를 자식이 재정의하는 것
성립 조건
- 메서드명, 매개변수, 반환형 동일
- 접근 제한자 같거나 더 넓은 범위
- 예외의 범위는 같거나 더 좁게
오버라이딩 시 throws하는 Exception의 개수와 상관없이 처리 범위가 같거나 후손 이여아 함
* Exception 클래스는 상속이 될 수록 상위 클래스 보다 예외의 내용이 더 상세하게 기술됨.
Java API에서 제공하는 Exception Class 만으로는 처리할 수 없는 예외가 있을 경우
사용자의 필요에 의해 생성하는 Exception Class.
Exception 발생하는 곳에서 throw new 예외클래스명()
으로 발생