1. 예외(Exception)와 예외 클래스
예외란? 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류를 말한다. 예외가 발생되면 프로그램은 곧바로 종료된다는 점과 에러와 비슷하다. 하지만 예외 처리(Exception Handling)을 통해 프로그램을 종료하지 않고 정상 실행 상태가 유지되도록 할 수 있다. 예외에는 두 가지 종류가 있다.
- 일반 예외와 실행 예외
일반 예외는 프로그램 실행시 발생할 가능성이 높기 때문에 컴파일 하는 과정에서 해당 예외 처리 코드가 있는지 검사한다. 만약 예외 처리 코드가 없다면 컴파일 오류가 발생한다.
실행 예외는 실행 시 예측할 수 없이 갑자기 발생하기 때문에 컴파일하는 과정에서 예외 처리 코드가 있는지 검사하지 않는다.
자바에서는 예외를 클래스로 관리한다. JVM은 프로그램을 실행하는 도중에 예외가 발생하면 해당 예외 클래스를 객체로 생성한다. 일반 예외와 실행 예외의 차이는 RuntimeException 클래스를 기준으로 구별한다. RuntimeException의 하위 클래스가 아니면 일반 예외 클래스이고, 하위 클래스이면 실행 예외 클래스이다.
- 실행 예외의 예시
NullPointerException : 객체 참조가 없는 상태, 즉 null 값을 갖는 참조 변수로 객체 접근 연산자인 도트(.)를 사용했을 때 발생한다.
ArrayIndexOutOfBoundsException : 배열에서 인덱스 범위를 초과할 경우 발생한다.
NumberFormatException : 데이터를 int 또는 double 타입으로 변환할 때, 문자열이 숫자로 변환될 수 있다면 숫자를 리턴하지만, 숫자로 변환될 수 없는 문자가 포함되어 있을 때 발생한다.
ClassCastException : Casting(타입 변환)은 상위 클래스와 하위 클래스 간에 발생하고 구현 클래스와 인터페이스 간에도 발생한다. 이러한 관계가 아니라면 클래스는 다른 타입으로 변환할 수 없기에 이 예외가 발생한다.
2. 예외 처리
자바 컴파일러는 소스 파일을 컴파일할 때 일반 예외가 발생할 가능성이 있는 코드를 발견하면 컴파일 에러를 발생시켜 개발자가 강제적으로 예외 처리 코드를 작성하도록 요구한다. 그러나 실행 예외의 경우 컴파일러가 체크할 수 없기 때문에 개발자의 경험을 바탕으로 예외 처리 코드를 작성해야 한다.
- 예외 처리 코드
try-catch-finally 블록은 생성자 내부와 메소드 내부에서 작성되어 일반 예외와 실행 예외가 발생할 경우 예외 처리를 할 수 있도록 해준다.
try {
// 예외 발생가능 코드
} catch(예외클래스 e) {
// 예외 처리
} finally {
// 항상 실행
}
1. try 블록에는 예외가 발생할 수 있는 코드를 작성한다.
2. try 블록의 코드가 예외 발생 없이 정상 실행되면 catch 블록의 코드는 실행되지 않고 finally 블록의 코드를 실행한다. 만약 try 블록의 코드에서 예외가 발생하면 즉시 실행을 멈추고 catch 블록으로 이동하여 예외 처리 코드를 실행한다. 그리고 finally 블록의 코드를 실행한다.
3. finally 블록은 생략 가능하다. 예외 발생 여부와 상관없이 항상 실행할 내용이 있을 경우에만 finally 블록을 작성해주면 된다. 심지어 try 블록과 catch 블록에서 return문을 사용하더라도 finally 블록은 항상 실행된다.
public class TryCatchFinallyEx {
public static void main(String[] args) {
String data1 = null;
String data2 = null;
try {
data1 = arg[0];
data2 = arg[1];
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("실행 매개값의 수가 부족합니다.");
return;
}
try {
int value1 = Integer.parseInt(data1);
int value2 = Integer.parseInt(data2);
int result = value1 + value2;
System.out.println(data1 + "+" + data2 + "=" + result);
} catch(NumberFormatException e) {
System.out.println("숫자로 변환할 수 없습니다.");
} finally {
System.out.println("다시 실행하세요.");
}
}
}
실행 예외 처리 예시이다. 이 예제를 실행시키면 "data = arg[0];"에서 ArrayIndexOutOfBoundsException이 발생해 "실행 매가값의 수가 부족합니다."가 출력된다. 또한 "int value1 = Integer.parseIng(data1);"에서는 NumberFormatException이 발생하여 "숫자로 변환할 수 없습니다."가 출력 된 후 finally로 가 "다시 실행하세요."가 출력된다.
- 예외 종류에 따른 처리 코드
1. 다중 catch : try 블록 내부에 다양한 예외가 발생할 수 있다. 이 경우 발생되는 예외 별로 예외처리 코드를 다르게 하려면 다중 catch 블록을 작성해야 한다.
try {
// ArrayIndexOutOfBoundsException 발생
// NumberFormatException 발생
} catch(ArrayIndexOutOfBoundsExcetpion e) {
// 예외 처리 1
} catch(NumberFormatException e) {
// 예외 처리 2
}
하지만 다중 Exception이 발생하더라도 ArrayIndexOutOfBoundsException이 발생하는 순간 try문이 종료되고 예외처리 1로 넘어가기 때문에 NumberFormatException에 대한 예외처리는 할 수 없다.
2. catch 순서 : 다중 catch 블록을 작성할 때, 상위 예외 클래스가 하위 예외 클래스보다 아래쪽에 위치해야 한다. try 블록에서 예외가 발생했을 때, 예외를 처리해줄 catch 블록은 위에서부터 차례대로 검색된다. 만약 상위 예외 클래스의 catch 블록이 위에 있다면, 하위 예외 클래스의 catch 블록은 실행되지 않는다.
try {
// ArrayIndexOutOfBoundsException 발생
// NumberFormatException 발생
} catch(Excetpion e) {
// 예외 처리 1
} catch(ArrayIndexOutOfBoundstException e) {
// 예외 처리 2
}
ArrayIndexOutOfBoundsException과 NumberFormatException 모두 Exception 클래스에 상속 받기 때문에 예외 처리 1만 작동하고 두 번째 catch 블록은 어떤 경우에라도 실행되지 않는다.
- 예외 떠넘기기
메소드 내부에서 예외가 발생할 수 있는 코드를 작성할 때 try-catch 블록으로 에외를 처리하는것이 기본이지만, 경우에 따라서는 메소드를 호출한 곳으로 예외를 떠넘길수 있다. 이때 사용하는 키워드가 throws 이다. throws는 메소드 선언부 끝에 작성된 다음 그 위에 떠넘길 예외 클래스를 쉼표로 구분해서 나열해 준다.
public void method1() {
try {
method2();
} catch(ClassNotFoundException e) {
System.out.println("클래스가 존재하지 않습니다.");
}
}
public void method2() throws ClassNotFoundException {
Class clazz = Class.forName("java.lang.String2");
}
thows 키워드가 붙어 있는 메소드는 반드시 try 블록 내에서 호출되어야 한다. 그리고 catch 블록에서 떠넘겨 받은 예외를 처리해야 한다.
'JAVA' 카테고리의 다른 글
[JAVA] 팩토리 패턴(Factory Pattern)이란? (0) | 2025.05.22 |
---|---|
[JAVA] 싱글톤 패턴(Singleton Pattern)이란? (0) | 2025.05.20 |
[JAVA] Heap 메모리 구조와 Garbage Collection (2) | 2024.12.08 |
[JAVA] 중첩클래스, 중첩인터페이스 (1) | 2024.12.03 |
[JAVA] 디자인패턴 - 데코레이터 패턴(Decorator Pattern)을 알아보자 (0) | 2024.12.03 |