[Java] 예외와 예외 처리
1. 에러와 예외의 차이
- 에러(error) : 컴퓨터 하드웨어의 오동작 또는 고장으로 인해 응용프로그램 실행 오류가 발생하는 것
- 예외(exception) : 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 발생하는 프로그램 오류, 에러 이외에
프로그램 자체에서 발생하는 오류
에러와 예외는 발생 시, 실행중인 프로그램이 곧바로 종료된다는 점이 같으나, 예외의 경우
'예외 처리(exception handling)'을 통해 프로그램이 종료되지 않고 정상 상태를 유지할 수 있도록 할 수 있다.
2. 예외와 예외 클래스
예외에는 두 가지 예외가 있다. 첫 번째로는 일반 예외(exception)이고 두 번째로는 실행 예외(runtime exception)이다.
일반 예외는 컴파일러 체크 예외라고도 하며, 프로그램 실행 시 발생할 가능성이 높기 때문에
자바소스를 컴파일 하는 과정에서 해당 예외 처리 코드가 있는지 검사한다.
실행 예외는 컴파일러 넌 체크 예외라고도 하며, 실행 시 예측할 수 없이 갑자기 발생하기에
컴파일 과정에서 예외처리 코드가 있는지 검사하지 않는다.
자바에서는 예외를 클래스로 관리하는데, 'JVM'이 프로그램을 실행하는 도중, 예외가 발생하면
해당 예외 클래스로 객체를 생성한다. 그리고 예외 처리 코드에서 예외 객체를 이용할 수 있도록 해준다.
모든 예외 클래스는 java.lang.Exception 클래스를 상속받으나 Runtime Exception의 하위클래스에 있는 경우
실행 예외 클래스이다.
3. 대표적인 실행 예외
- NullPointerException
null 값을 갖는 참조 변수로 객체 접근 연산자 도트(.)를 사용했을 때 발생.
객체가 없는 상태에서 객체를 사용하려 하는 경우에 발생하는 예외 - ArrayIndexOutOfBoundsException
배열에서 인덱스 범위를 초과할 경우 발생하는 실행 예외
실행 매개값을 주지 않은 경우에 인덱스를 사용할 수 없으므로 발생하기도 한다. - NumberFormatException
문자열을 숫자로 변경하는 경우에, 숫자가 아닌 문자열이 포함돼있을 경우 발생하는 예외
Integer, Double과 같이 포장 클래스를 통한 변환시 발생할 수 있다. - ClassCastException
타입 변환(강제, Casting)을 할 시, 상위 클래스-하위클래스 또는 인터페이스-구현 클래스간에
변환할 수 없는 타입을 강제 변환 하려할 시 발생하는 예외이다.
이를 처리하기 위해 instanceof 클래스이름(객체가 해당 클래스의 객체인지 확인하는 연산자)를
if문과 함께 사용하여 검증하는 방법을 주로 사용한다.
4. 예외처리
자바 컴파일러는 소스 파일을 컴파일 할 때 일반 예외가 발생할 가능성이 있는 코드를 발견하면
컴파일 에러를 발생시켜 강제적으로 예외 처리 코드를 작성하도록 요구하나, 실행예외의 경우
컴파일러 넌 체크 타입이기에 개발자가 경험을 토대로 예외 처리를 해야 한다.
예외 처리를 사용하기 위해 try-catch-finally 블록을 이용한다.
try{
예외 발생 가능한 코드
} catch(예외클래스 e) {
예외 처리
} finally {
항상 실행;
}
- try 블록에는 예외 발생 가능한 코드가 위치한다.
- 예외 발생없이 정상 실행되면, catch를 거치지 않고 finally 블록의 코드를 실행한다.
- 예외가 발생하면, 즉시 실행을 멈추고 catch 블록으로 이동하여 예외 처리 코드를 실행한 후 finally 블록 코드를 처리한다.
- finally는 생략이 가능하나 예외 발생 여부와 무관하게 실행할 내용이 있을 경우 작성한다.
- finally는 try, catch 블록에서 return문을 사용하더라도 실행된다.
try 내부에서는 다양한 예외가 발생할 수 있다. 이 때 예외별로 예외처리를 하기 위해 다중 catch 블록을 작성한다.
try 블록에서 해당 타입의 예외가 발생하면 catch 블록을 실행하는데, catch 블록이 여러개라도 단 하나의 catch 블록만
실행한다. 그 이유는 하나의 예외가 발생하면 그 즉시 실행을 멈추고 예외처리를 하기 때문이다.
단, 다중 catch 블록 작성 시 상위 예외클래스가 하위 예외 클래스보다 아래에 위치해야한다.
만약 상위 예외 클래스(예를 들면 Exception같은 큰)가 위에 있다면, 하위 예외클래스의 catch는 실행되지 않는다.
왜냐하면 하위 예외클래스는 상위 예외를 상속하기에 상위 예외 타입도 되기 때문이다.
기본적으로 위와 같이 try-catch문을 통해 예외를 처리하는 것이 기본이지만, 경우에 따라서는
메소드를 호출한 곳으로 예외를 떠넘길 수도 있는데, 이 때 사용하는 키워드가 throws 이다.
메소드 선언부 끝에 throws 키워드를 작성하면, 메소드에서 해당 예외를 처리하지 않고, 메소드를 '호출한 곳'에
예외 처리를 떠넘긴다. throws 키워드 뒤에는 떠넘길 예외클래스를 쉼표로 구분해서 나열하면 된다.
출처 : 혼자 공부하는 자바, 한빛 미디어