예외 처리
예외란 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류를 말한다.
예외는 곧바로 종료되는 에러와 비슷하지만 예외 처리를 통해 프로그램을 종료하지 않고
정상 실행 상태가 유지를 할 수 있다는 점에서 다르다고 할 수 있다.
예외의 종류
1. 일반 예외
프로그램 실행 시 예외가 발생할 가능성이 높기 때문에 자바 소스를 컴파일하는 과정에서
해당 예외 처리 코드가 있는지 검사하는 것을 말한다.
2.실행 예외
실행 시 예측할 수 없이 갑자기 발생하기 때문에 컴파일하는 과정에서
예외 처리 코드가 있는지 검사하지 않는 것을 말한다.
RuntimeException의 하위 클래스가 아니면 일반 예외 클래스이고, 하위 클래스이면 실행 예외 클래스이다.
클래스 상속 관계에서 부모에 RuntimeException이 있다면 실행 예외 클래스이다.
실행 예외의 종류
- NullPointerException : null 값을 갖는 참조 변수로 객체 접근 연산자인 도트(.)를 사용했을 때 발생함
- ArrayIndexOutOfBoundsException : 베열에서 인덱스 범위를 초과할 경우 발생함
- NumberFormatException : 문자열로 되어있는 데이터를 숫자로 변경하는 할 때
숫자로 변환될 수 없는 문자가 포함되어 있을 경우에 발생함
- ClassCastException : 하위 유형이 아닌 유형에 대한 참조를 캐스팅하려고 했을 때 발생함
- ArithmeticException : 산술적인 연산에 오류가 있을 때 발생함
- IllegalArgumentException : 매개변수가 의도하지 않은 상황을 유발시킬 때 발생함
try-catch-finally 블록
try{
// 예외 발생 가능 코드
}catch(예외 클래스){
// 예외 처리
}finally{
// 항상 실행
}
다중 catch문
try 블록 내부는 다양한 예외가 발생할 수 있다. 다양한 예외별로 예외 처리 코드를 다르게 사용할 때
필요한 것이 다중 catch문이다. catch 블록이 여러 개이더라도 단 하나의 catch문만 실행된다.
왜냐하면 try 블록에서 동시에 예외가 발생하는 것이 아니라 하나의 예외가 발생한다면 즉시 실행을 멈추고
해당 catch 블록으로 이동하기 때문이다. 다중 catch문을 사용할 때 가장 중요한 점이 있다.
상위 예외 클래스가 하위 예외 클래스보다 아래쪽에 위치해야 한다는 점이다.
try 블록에서 예외가 발생했을 때 예외를 처리하는 catch 블록이 위에서부터 차례로 검색되는데
만약에 상위 예외 클래스를 하위 예외 클래스 위쪽에 위치시킨다면 하위 예외 클래스가 상위 예외 클래스를
상속했기 때문에 상위 예외 클래스로 실행되기 때문이다. 아래의 코드를 참고하도록 하자.
- 잘못된 코드
// 잘못된 코드
import java.sql.SQLException;
public class ExceptionEx {
public static void main(String[] args) {
try {
// 예외 발생 가능 코드
}catch(Exception e) {
// 예외 처리
}catch(SQLException se) {
// 예외 처리
}
}
}
- 올바른 코드
// 올바른 코드
import java.sql.SQLException;
public class ConnectionEx2 {
public static void main(String[] args) {
try {
// 예외 발생 가능 코드
}catch(SQLException se) {
// 예외 처리
}catch(Exception e) { // 상위 예외 클래스가 아래쪽에 위치
// 예외 처리
}
}
}
throws
예외가 발생하면 상위 메서드로 예외를 던진다. (떠넘김)
throws 키워드가 붙어 있는 메소드는 반드시 try 블록 내에서 호출되어야 한다.
그리고 catch 블록에서 떠넘겨 받은 예외를 처리해야 한다.
public class ExceptionEx {
public static void main(String[] args) {
try {
int x = Integer.parseInt(args[0]);
int y = Integer.parseInt(args[1]);
divide(x, y);
}catch(ArithmeticException ae) {
System.out.println("나누는 숫자는 0이 될 수 없습니다.");
}catch(Exception ex) {
System.out.println("예외가 발생했습니다. : " + ex);
}finally {
System.out.println("무조건 실행되는 문장");
}
}
private static void divide(int x, int y) throws ArithmeticException{
System.out.println(x + "/" + y + " = " + (x/y));
}
}
이 코드는 파라미터를 전달하여 실행하므로
해당 파일의 마우스 오른쪽 버튼을 클릭해서 아래와 같이 실행해주자.
20과 10으로 파라미터를 전달했으므로 아래와 같이 결과가 출력된다.
// 결과
20/10 = 2
무조건 실행되는 문장
그렇다면 예외가 발생한다면 어떻게 출력되는지 확인해보도록 하자.
이번엔 20과 0을 각각 파라미터로 넘겨주었다.
만약에 try-catch-finally 블록을 이용해서 예외 처리를 해주지 않았다면
아래의 사진과 같이 ArithmeticException이 발생했을 것이다.
하지만 우리는 예외 처리를 해주었으므로 아래와 같은 결과가 출력되는 것을 볼 수 있다.
// 결과
나누는 숫자는 0이 될 수 없습니다.
무조건 실행되는 문장
throw
예외를 강제로 발생시킨 후, 상위 블럭이나 catch문으로 예외를 던진다.
public class ExceptionEx {
public static void main(String[] args) {
int speed = Integer.parseInt(args[0]);
try {
if(speed < 0) {
throw new IllegalArgumentException();
}else {
System.out.println("속도 : " + speed);
}
}catch(IllegalArgumentException e) {
System.out.println("속도는 음수가 될 수 없습니다.");
}
}
}
throws 예제에서 했던 것처럼 똑같이 파라미터를 전달해주면 되는데
0 이상의 숫자로 전달해준다면 속도가 출력될 것이고,
파라미터를 음수로 전달한다면 "속도는 음수가 될 수 없습니다."라고 출력될 것이다.
이는 Exception을 던질 때 예외 내용을 던져주지 않기 때문에
위와 같이 개발자가 직접 예외 메시지를 작성해야한다.
'국비 지원 > JAVA' 카테고리의 다른 글
[JAVA] 바이트 기반 입출력 스트림 (1) (0) | 2023.06.04 |
---|---|
[JAVA] ArrayList와 제네릭(Generic) (0) | 2023.05.28 |
[JAVA] final과 상수(static final) (0) | 2023.05.21 |
[JAVA] 익명 함수와 람다 함수 (0) | 2023.05.21 |
[JAVA] 다중 상속과 추상 클래스와 인터페이스의 차이점 (0) | 2023.05.20 |