예외(Exception) 는 코드 로직에 문제가 있거나 사용자의 실수 등으로 인해 발생하는 상황을 일컫는데,
예를 들어 어떤 수를 0으로 나누어 발생하는 ArithmeticException, 파일을 찾을 수 없어서 발생하는 FileNotFoundException 등이 존재한다.
예외는 사전에 예측 가능하고 미리 대응을 할 수 있는데, 이를 예외 처리 라고 한다.
예외 처리의 주된 목적은 프로그램의 비정상적인 종료를 방지하고,
사용자에게 에러 정보를 제공하여 가능한 조치를 취할 수 있도록 하는 것이다.
예외와 함께 언급되는 오류는 예외와 어떤 차이가 있을까?
오류(Error)는 시스템 레벨에서 발생하는 심각한 문제를 지칭한다.
예를 들어 무한 루프에 빠진 재귀 호출로 인한 StackOverflowError, 메모리 부족으로 인한 OutOfMemoryError 등이 존재한다.
오류 는 개발자가 사전에 예측하여 방지할 수 없고 대부분 회복이 불가능하다.
오류 가 발생하면 어떤 오류 로 프로그램이 종료되었는지 확인하고 대응하는 사후조치를 취한다.
try 블럭 내에는 예외 발생 가능성이 있는 코드가 들어간다. 만약 해당 코드가 예외를 발생시킨다면 catch 블럭 내 코드가 수행되고, 그렇지 않다면 수행되지 않는다.catch 블럭은 예외가 발생했을 경우 캐치해서 대응한다. 이렇게 함으로써 프로그램은 정상적으로 실행이 유지될 수 있다.int num;
try {
num = 10 / 0 // 예외가 발생할 수 있는 코드
} catch (ArithmeticException e) {
System.out.println(e.getMessage()) // 예외 처리 코드
}
프로그램 실행 과정에서 예외가 발생하든 발생하지 않든 실행시켜야할 코드가 있을 수 있다.
finally 블럭 내에는 예외 발생 여부와 관계없이 반드시 실행되는 코드가 들어간다.
int num;
try {
num = 10 / 0 // 예외가 발생할 수 있는 코드
} catch (ArithmeticException e) {
System.out.println(e.getMessage()) // 예외 처리 코드
} finally {
System.out.println("반드시 실행") // 예외 여부와 관계없이 무조건 실행
}
throw 는 직접 예외를 발생시킬 때 사용된다. throw 다음에는 예외 객체를 명시하여 사용한다.throws 는 메서드 선언 시 사용되며, 해당 메서드가 특정 예외를 발생시킬 수 있음을 알려준다.public int divide(int firstNum, int secondNum) throws ArithmeticException {
if (secondNum == 0) {
throw new ArithmeticException("0으로 나눌 수 없습니다."); // 0으로 나눌 때 예외 발생
}
return firstNum / secondNum;
}
Checked Exception 은 컴파일 시점에서 체크되는 예외이다. 예외 처리를 강제하며, 반드시 try-catch 블록으로 처리하거나 메서드 선언부에 throws 키워드를 사용하여 선언해야 한다. 대표적인 예로 IOException, SQLException 등이 있다.
public void readFile(String filePath) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(filePath));
String line = reader.readLine();
reader.close();
}
위 예제에서 readFile 메서드는 IOException 을 throws 키워드를 통해 선언하고 있다.
Unchecked Exception 은 런타임 시점에서 발생하는 예외로, 예외 처리가 강제되지 않는다. RuntimeException 을 상속하며, 대표적인 예로 NullPointerException, ArrayIndexOutOfBoundsException 등이 있다.
public void divide(int a, int b) {
if (b == 0) {
throw new ArithmeticException("0으로 나눌 수 없습니다.");
}
System.out.println(a / b);
}
위 예제에서 divide 메서드는 ArithmeticException 을 직접 던지고 있으며, 이는 Unchecked Exception 이다.
예외 처리를 처음 알게 되었을 때는 '그냥 조건문으로 해결하면 되는 것이 아닌가?' 라고 생각하며
예외 처리의 필요성에 대한 의문을 품기도 하였다.
하지만 예외 처리는 단순히 조건문으로 해결할 수 없는 문제들을 해결함으로써
프로그램의 안정성과 신뢰성을 향상시킬 수 있기 때문에,
전반적인 소프트웨어 품질을 향상시키는 중요한 역할을 한다는 것을 알게 되었다.